代码之家  ›  专栏  ›  技术社区  ›  Bernie Perez

Java AES和使用我自己的密钥

  •  81
  • Bernie Perez  · 技术社区  · 14 年前

    我想用我自己的密钥用AES加密一个字符串。但是钥匙的长度有点问题。你能看看我的代码,看看我需要修复/更改什么吗?

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

    现在我有个例外” 无效的aes密钥长度:86字节 “。我需要按一下我的钥匙吗?我该怎么做?

    我还需要为欧洲央行或中央银行设置什么吗?

    谢谢

    6 回复  |  直到 6 年前
        1
  •  117
  •   mknjc    14 年前

    您应该使用sha-1从您的密钥生成一个哈希,并将结果修剪为128位(16字节)。

    另外,不要从字符串到 GETBYTESE() 它使用平台默认字符集。因此,密码“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位作为密钥大小,则需要下载“Java加密扩展(JCE)无限强度管辖权策略文件”。 Oracle download link ,使用sha-256作为哈希并删除 复制品 线。 “ecb”是默认密码模式,“pkcs5padding”是默认填充。 您可以使用不同的密码模式和填充模式 密码.getInstance 使用以下格式的字符串:“cipher/mode/padding”

    对于使用cts和pkcs5padding的aes,字符串为:“aes/cts/pkcs5padding”

        2
  •  13
  •   Keibosh    14 年前

    您应该使用keygenerator来生成密钥,

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

    看看教程 here

    这是基于密码的加密代码,密码是通过系统输入的。在中,如果需要,可以将其更改为使用存储的密码。

            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);
    
        3
  •  4
  •   Shankar Murthy    11 年前
    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);
        }
    }
    
        4
  •  1
  •   Community CDub    8 年前

    这个WLL工作。

    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;
          }
     }
    
        5
  •  0
  •   sonnykwe    8 年前
        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();
    
        6
  •  0
  •   Mike    6 年前

    MD5,AES,无填充

    import static javax.crypto.Cipher.DECRYPT_MODE;
    import static javax.crypto.Cipher.ENCRYPT_MODE;
    import static org.apache.commons.io.Charsets.UTF_8;
    import java.security.InvalidKeyException;
    import java.security.Key;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Base64;
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.spec.SecretKeySpec;
    
    public class PasswordUtils {
    
        private PasswordUtils() {}
    
        public static String encrypt(String text, String pass) {
            try {
                MessageDigest messageDigest = MessageDigest.getInstance("MD5");
                Key key = new SecretKeySpec(messageDigest.digest(pass.getBytes(UTF_8)), "AES");
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(ENCRYPT_MODE, key);
    
                byte[] encrypted = cipher.doFinal(text.getBytes(UTF_8));
                return new String(Base64.getEncoder().encode(encrypted), UTF_8);
    
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
                throw new RuntimeException("Cannot encrypt", e);
            }
        }
    
        public static String decrypt(String text, String pass) {
            try {
                MessageDigest messageDigest = MessageDigest.getInstance("MD5");
                Key key = new SecretKeySpec(messageDigest.digest(pass.getBytes(UTF_8)), "AES");
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(DECRYPT_MODE, key);
    
                byte[] decoded = Base64.getDecoder().decode(text.getBytes(UTF_8));
                byte[] decrypted = cipher.doFinal(decoded);
                return new String(decrypted, UTF_8);
    
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
                throw new RuntimeException("Cannot decrypt", e);
            }
        }
    }