Java使用AES 256和128对称密钥加密

时间:2011-06-30 17:09:53

标签: java aes encryption

我是密码技术的新手。我发现这段代码可以进行对称加密。

byte[] key = //... secret sequence of bytes
byte[] dataToSend = ...
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k = new SecretKeySpec(key, "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encryptedData = c.doFinal(dataToSend);

它的工作。在这里,我可以使用自己的密码。那就是我需要的东西。但我不知道怎么做128或256 Symmetric Enctryption。 如何在代码中使用128和256键?

5 个答案:

答案 0 :(得分:16)

AES是使用128位还是256位模式取决于密钥的大小,密钥长度必须为128或256位。通常,您不会将密码用作密钥,因为密码很少具有您需要的确切长度。相反,您可以使用某些密钥派生函数从密码派生加密密钥。

非常简单的示例:获取密码的MD5以获得128位密钥。如果需要256位密钥,可以使用SHA-256获取密码的256位哈希值。密钥派生函数通常运行此散列数百次并使用额外的盐。查看http://en.wikipedia.org/wiki/Key_derivation_function了解详情。

另请注意:要运行超过128位的加密,您需要从http://www.oracle.com/technetwork/java/javase/downloads/index.html下载并安装“Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files 6”。

答案 1 :(得分:6)

128位

的答案

以下方法是使用AES加密加密字符串(valueEnc):

private static final String ALGORITHM = "AES"; 

public String encrypt(final String valueEnc, final String secKey) { 

    String encryptedVal = null;

    try {
        final Key key = generateKeyFromString(secKey);
        final Cipher c = Cipher.getInstance(ALGORITHM);
        c.init(Cipher.ENCRYPT_MODE, key);
        final byte[] encValue = c.doFinal(valueEnc.getBytes());
        encryptedVal = new BASE64Encoder().encode(encValue);
    } catch(Exception ex) {
        System.out.println("The Exception is=" + ex);
    }

    return encryptedVal;
}

下一个方法将解密AES加密字符串(encryptedVal):

    public String decrypt(final String encryptedValue, final String secretKey) {

    String decryptedValue = null;

    try {

        final Key key = generateKeyFromString(secretKey);
        final Cipher c = Cipher.getInstance(ALGORITHM);
        c.init(Cipher.DECRYPT_MODE, key);
        final byte[] decorVal = new BASE64Decoder().decodeBuffer(encryptedValue);
        final byte[] decValue = c.doFinal(decorVal);
        decryptedValue = new String(decValue);
    } catch(Exception ex) {
        System.out.println("The Exception is=" + ex);
    }

    return decryptedValue;
}

secKey是一个128位密钥,在BASE64Encoder中编码。以下方法中的BASE64Decoder生成适当的128位密钥

private Key generateKeyFromString(final String secKey) throws Exception {
    final byte[] keyVal = new BASE64Decoder().decodeBuffer(secKey);
    final Key key = new SecretKeySpec(keyVal, ALGORITHM);
    return key;
}

答案 2 :(得分:3)

您可以使用这样的简单KeyGenerator对象:

KeyGenerator generator = KeyGenerator.getInstance("AES/CTR/PKCS5PADDING");
generator.init(128);
SecretKey key = generator.generateKey();
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
...

答案 3 :(得分:1)

来自Java's docs for Cipher.init(...)

  

public final void init(int opmode,                          钥匙)

     

抛出:       InvalidKeyException - 如果给定的键不适合初始化   这个密码,或者如果这个密码是   被初始化用于解密和   需要算法参数   不能从给定的确定   密钥,或者给定密钥是否具有密钥大小   超过允许的最大值   密钥化(由...确定)   配置的管辖区政策文件)。

对我来说,这意味着,正如Martijn Courteaux在他的评论中所说,你应该使用256位的密钥(即用一个包含32个字节的字节数组初始化SecretKeySpec),密码将接受并使用它,或拒绝它并在其大小不可接受的情况下抛出异常。

如果你遇到异常,可能是因为你没有安装无限强度加密文件,(默认的JDK安装允许128位密钥,如crypto spec document中所述)。下载无限强度加密包here

答案 4 :(得分:0)

public class CipherUtils
{
    private static byte[] key = {
            0x74, 0x68, 0x69, 0x73, 0x49, 0x73, 0x41, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79
    };//"thisIsASecretKey";

    public static String encrypt(String strToEncrypt)
    {
        try
        {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            final String encryptedString = Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes()));
            return encryptedString;
        }
        catch (Exception e)
        {
           e.printStackTrace();
        }
        return null;
    }
}