加密期间共享密钥和IV的问题

时间:2018-04-02 15:33:33

标签: java security encryption aes

我在Java中实现了以下AES算法,但问题出现的原因是加密是在设计时执行的,而解密是在运行时执行的,因此解密在运行时失败。

在解密期间,IvParameterSpec和SecretKey为空,因为它们在完全不同的时间被调用。如何在这种情况下实施?

static IvParameterSpec ivspec =null;
static  SecretKey secKey=null;

public static SecretKey getSecretEncryptionKey(){       
    KeyGenerator generator=null;
    try {
        generator = KeyGenerator.getInstance("AES");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

    }
    generator.init(128); // The AES key size in number of bits
    secKey = generator.generateKey();
    return secKey;
}


 public static String encrypt(String text) throws GeneralSecurityException {
    if (text == null || text.isEmpty()) {
        return "";
    }

     secKey = getSecretEncryptionKey();
     byte[] iv = new byte[128/8];
     Random randomNumber = new Random();        
     randomNumber.nextBytes(iv);
     ivspec = new IvParameterSpec(iv);

     Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
     ci.init(Cipher.ENCRYPT_MODE, secKey, ivspec); 
     byte[] byteCipherText = ci.doFinal(text.getBytes());
     return String.format("{%s}", base64Encode(byteCipherText));
}

public static String decrypt(String text)  {
    if (text == null || text.isEmpty()) {
        return "";
    }
    if (!text.startsWith("{") || !text.endsWith("}")) {
        return text;
    }
     Cipher ci;
     byte[] bytePlainText =null;
    try {
        ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
        ci.init(Cipher.DECRYPT_MODE, secKey,ivspec);
         byte[] decryptText=base64Decode(text);          
         bytePlainText = ci.doFinal(decryptText);
    } catch (Exception ex) {
        // TODO Auto-generated catch block
        ex.printStackTrace();
    } 


     return new String(bytePlainText,StandardCharsets.UTF_8);
}

1 个答案:

答案 0 :(得分:0)

我已经实现了如下算法:

获取密钥:

private static SecretKey getKey() {

    System.out.println("Key Length " + KEY_LENGTH);
    try {
        return new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
                .generateSecret(new PBEKeySpec(CIPHER_KEY.toCharArray(), CIPHER_KEY.getBytes(), 10000, KEY_LENGTH))
                .getEncoded(), "AES");
    } catch ( Exception e) {

    }
    return null;
}

加密方法:

public static String encrypt(String text) throws GeneralSecurityException {
    if (text == null || text.isEmpty()) {
        return "";
    }

    Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
    ci.init(Cipher.ENCRYPT_MODE, getKey(), getIvParameterSpec());
    return String.format("{%s}", base64Encode(ci.doFinal(text.getBytes())));
}

解密方法:

 public static String decrypt(String text) {
    if (text == null || text.isEmpty()) {
        return "";
    }
    if (!text.startsWith("{") || !text.endsWith("}")) {
        return text;
    }
    Cipher ci;
    byte[] bytePlainText = null;
    try {

        ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
        ci.init(Cipher.DECRYPT_MODE, getKey(), getIvParameterSpec());            
        bytePlainText = ci.doFinal(base64Decode(text));

    } catch (Exception e) {
        // TODO Auto-generated catch block
        System.out.println(e.toString());
    }

    return new String(bytePlainText, StandardCharsets.UTF_8);
}