已知解密方法的Java中的加密

时间:2019-03-18 07:49:07

标签: java encryption byte aes

我尝试使用Java进行加密和解密机制。我找到了一些用于解密的代码,但我不知道如何加密。哪种加密方法将与这种解密方法兼容:

private byte[] padKey(byte[] key) {
        byte[] paddedKey = new byte[32];
        System.arraycopy(key, 0, paddedKey, 0, key.length);
        return paddedKey;
    }

    private byte[] unpad(byte[] data) {     
        byte[] unpaddedData = new byte[data.length - data[data.length - 1]];
        System.arraycopy(data, 0, unpaddedData, 0, unpaddedData.length);
        return unpaddedData;
    }


public String decrypt(String encodedJoinedData) throws Exception {

        // Base64-decode the joined data
        byte[] joinedData = Base64.decode(encodedJoinedData); 

        // Get IV and encrypted data
        byte[] iv = new byte[16];
        System.arraycopy(joinedData, 0, iv, 0, iv.length);
        byte[] encryptedData = new byte[joinedData.length - iv.length];
        System.arraycopy(joinedData, iv.length, encryptedData, 0, encryptedData.length);

        // Pad key
        byte[] key = padKey("SiadajerSiadajer".getBytes()); 
        Key aesKey = new SecretKeySpec(key, "AES");

        // Specify CBC-mode
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); 
        cipher.init(Cipher.DECRYPT_MODE, aesKey, ivParameterSpec);

        // Decrypt data
        byte[] decryptedData = cipher.doFinal(encryptedData);

        // Remove custom padding
        byte[] unpaddedData = unpad(decryptedData);         

        return new String(unpaddedData);
    }

1 个答案:

答案 0 :(得分:0)

如果您正在寻找与decrypt方法相对应的加密方法,则只需简单地逆转decrypt方法中的过程即可。必须在encrypt方法的主体中执行以下操作(让plainText为包含纯文本的String参数)

  1. 添加自定义填充

    // Pad data (custom padding)
    byte[] paddedData = pad(plainText.getBytes(), 16);
    
  2. 加密纯文本

    // Pad key 
    byte[] key = padKey("SiadajerSiadajer".getBytes()); 
    Key aesKey = new SecretKeySpec(key, "AES");
    
    // Specify block-cipher (AES), mode (CBC) and padding (PKCS5)
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    
    // Create random IV
    SecureRandom secureRandom = new SecureRandom();
    byte iv[] = new byte[cipher.getBlockSize()];
    secureRandom.nextBytes(iv);
    IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); 
    
    // Encrypt data
    cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParameterSpec);
    byte[] encryptedData = cipher.doFinal(paddedData);
    
  3. 加入IV和加密数据

    // Join IV and encrypted data
    byte[] joinedData = new byte[iv.length + encryptedData.length];  
    System.arraycopy(iv, 0, joinedData, 0, iv.length);
    System.arraycopy(encryptedData, 0, joinedData, iv.length, encryptedData.length);
    
  4. 对连接的数据进行64位编码

    // Base64-encode data
    String encodedJoinedData = Base64.encode(joinedData, 0);
    

最后,必须返回encodedJoinedData

此外,您必须实现自定义填充。以下方法实现了自定义PKCS5-Padding,并且可能与unpad方法相对应:

private byte[] pad(byte[] data, int size) {
    byte padLength = (byte)(size - (data.length % size));
    byte[] paddedData = new byte[data.length + padLength];
    System.arraycopy(data, 0, paddedData, 0, data.length);
    for (int i = data.length; i < paddedData.length; i++)
        paddedData[i] = (byte)padLength;
    return paddedData;
}

顺便说一句,您的decrypt方法(以及encrypt方法)存在一些问题:

  • 您不应使用硬编码的密钥,但这可能仅用于测试目的。有关创建安全AES密钥的信息,请参见How to create a secure random AES key in Java?
  • 最明显的缺陷是,它在decrypt / encrypt方法中未填充/填充两次,这没有任何意义。因此,请删除所选的PKCS5-Padding(即从AES/CBC/PKCS5Padding更改为AES/CBC/NoPadding)或同时删除decrypt-和encrypt-方法中的自定义填充(前提是在您的项目范围内)。