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

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

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键?

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下载并安装“Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files 6” 。 /index.html 。

答案为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; } 

您可以使用这样的简单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); ... 

来自Java的Cipher.init(...)文档 :

public final void init(int opmode,Key key)

抛出:InvalidKeyException – 如果给定的密钥不适合初始化此密码,或者此密码正在初始化以进行解密并且需要无法从给定密钥确定的算法参数,或者给定密钥的密钥大小超过允许的最大值keysize(根据配置的权限策略文件确定)。

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

如果您遇到exception,可能是因为您没有安装无限强度加密文件(默认JDK安装允许128位密钥,如此加密规范文档中所述 )。 在这里下载无限强度加密包。

 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; } }