Java AES和使用我自己的密钥

我想用我自己的密钥使用AESencryption一个string。 但是我在密钥的位长方面遇到了麻烦。 你可以检查我的代码,看看我需要修复/更改。

public static void main(String[] args) throws Exception { String username = "bob@google.org"; String password = "Password1"; String secretID = "BlahBlahBlah"; String SALT2 = "deliciously salty"; // Get the Key byte[] key = (SALT2 + username + password).getBytes(); System.out.println((SALT2 + username + password).getBytes().length); // Need to pad key for AES // TODO: Best way? // Generate the secret key specs. SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); // Instantiate the cipher Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); byte[] encrypted = cipher.doFinal((secrectID).getBytes()); System.out.println("encrypted string: " + asHex(encrypted)); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); byte[] original = cipher.doFinal(encrypted); String originalString = new String(original); System.out.println("Original string: " + originalString + "\nOriginal string (Hex): " + asHex(original)); } 

现在我得到一个exception“ 无效的AES密钥长度:86字节 ”。 我需要密钥吗? 我应该怎么做?

我也需要为ECB或CBC设置任何东西吗?

谢谢

您应该使用SHA-1从您的密钥中生成散列,并将结果修剪为128位(16字节)。

此外,不要通过getBytes()从string生成字节数组,而是使用平台默认的字符集。 所以密码“blaöä”在不同的平台上产生不同的字节数组。

 byte[] key = (SALT2 + username + password).getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 16); // use only first 128 bit SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); 

编辑:如果您需要256位的密钥大小,您需要下载“Javaencryption扩展(JCE)无限强度pipe辖权策略文件” Oracle下载链接 ,使用SHA-256作为散列并删除Arrays.copyOf行。 “ECB”是默认的密码模式,“PKCS5Padding”是默认的填充。 您可以使用不同的密码模式和填充模式,通过Cipher.getInstancestring使用以下格式:“密码/模式/填充”

对于使用CTS和PKCS5Padding的AES,string为:“AES / CTS / PKCS5Padding”

您应该使用KeyGenerator生成密钥,

AES密钥长度为128,192和256位,具体取决于您要使用的密码。

看看这里的教程

这里是基于密码的encryption的代码,这个密码是通过System.ininput的,如果你愿意,你可以改变它来使用存储的密码。

  PBEKeySpec pbeKeySpec; PBEParameterSpec pbeParamSpec; SecretKeyFactory keyFac; // Salt byte[] salt = { (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c, (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99 }; // Iteration count int count = 20; // Create PBE parameter set pbeParamSpec = new PBEParameterSpec(salt, count); // Prompt user for encryption password. // Collect user password as char array (using the // "readPassword" method from above), and convert // it into a SecretKey object, using a PBE key // factory. System.out.print("Enter encryption password: "); System.out.flush(); pbeKeySpec = new PBEKeySpec(readPassword(System.in)); keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec); // Create PBE Cipher Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); // Initialize PBE Cipher with key and parameters pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec); // Our cleartext byte[] cleartext = "This is another example".getBytes(); // Encrypt the cleartext byte[] ciphertext = pbeCipher.doFinal(cleartext); 
 import java.security.Key; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import sun.misc.*; import java.io.BufferedReader; import java.io.FileReader; public class AESFile { private static String algorithm = "AES"; private static byte[] keyValue=new byte[] {'0','2','3','4','5','6','7','8','9','1','2','3','4','5','6','7'};// your key // Performs Encryption public static String encrypt(String plainText) throws Exception { Key key = generateKey(); Cipher chiper = Cipher.getInstance(algorithm); chiper.init(Cipher.ENCRYPT_MODE, key); byte[] encVal = chiper.doFinal(plainText.getBytes()); String encryptedValue = new BASE64Encoder().encode(encVal); return encryptedValue; } // Performs decryption public static String decrypt(String encryptedText) throws Exception { // generate key Key key = generateKey(); Cipher chiper = Cipher.getInstance(algorithm); chiper.init(Cipher.DECRYPT_MODE, key); byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedText); byte[] decValue = chiper.doFinal(decordedValue); String decryptedValue = new String(decValue); return decryptedValue; } //generateKey() is used to generate a secret key for AES algorithm private static Key generateKey() throws Exception { Key key = new SecretKeySpec(keyValue, algorithm); return key; } // performs encryption & decryption public static void main(String[] args) throws Exception { FileReader file = new FileReader("C://myprograms//plaintext.txt"); BufferedReader reader = new BufferedReader(file); String text = ""; String line = reader.readLine(); while(line!= null) { text += line; line = reader.readLine(); } reader.close(); System.out.println(text); String plainText = text; String encryptedText = AESFile.encrypt(plainText); String decryptedText = AESFile.decrypt(encryptedText); System.out.println("Plain Text : " + plainText); System.out.println("Encrypted Text : " + encryptedText); System.out.println("Decrypted Text : " + decryptedText); } } 

这将工作。

 public class CryptoUtils { private final String TRANSFORMATION = "AES"; private final String encodekey = "1234543444555666"; public String encrypt(String inputFile) throws CryptoException { return doEncrypt(encodekey, inputFile); } public String decrypt(String input) throws CryptoException { // return doCrypto(Cipher.DECRYPT_MODE, key, inputFile); return doDecrypt(encodekey,input); } private String doEncrypt(String encodekey, String inputStr) throws CryptoException { try { Cipher cipher = Cipher.getInstance(TRANSFORMATION); byte[] key = encodekey.getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 16); // use only first 128 bit SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); byte[] inputBytes = inputStr.getBytes(); byte[] outputBytes = cipher.doFinal(inputBytes); return Base64Utils.encodeToString(outputBytes); } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | IOException ex) { throw new CryptoException("Error encrypting/decrypting file", ex); } } public String doDecrypt(String encodekey,String encrptedStr) { try { Cipher dcipher = Cipher.getInstance(TRANSFORMATION); dcipher = Cipher.getInstance("AES"); byte[] key = encodekey.getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 16); // use only first 128 bit SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); dcipher.init(Cipher.DECRYPT_MODE, secretKeySpec); // decode with base64 to get bytes byte[] dec = Base64Utils.decode(encrptedStr.getBytes()); byte[] utf8 = dcipher.doFinal(dec); // create new string based on the specified charset return new String(utf8, "UTF8"); } catch (Exception e) { e.printStackTrace(); } return null; } } 
  byte[] seed = (SALT2 + username + password).getBytes(); SecureRandom random = new SecureRandom(seed); KeyGenerator generator; generator = KeyGenerator.getInstance("AES"); generator.init(random); generator.init(256); Key keyObj = generator.generateKey();