我试图确定这段代码是否会占用大量文件的内存。有人能告诉我,我是否可以做些什么来提高内存的效率,或者java.crypto就是这样工作的?
private byte[] symmetricDecryptAttachment(byte[] encryptedAttachmentBytes, byte[] keyBytes) throws IOException, GeneralSecurityException, EIPException {
byte[] decryptedValue = null;
// TODO: change to use non-deprecated method ConfigurationManager:getParsedStringValue() instead of getStringValue() which is deprecated
String decryptionAlgorithm = manager.getStringValue(SymmetricDecryptionAlgorithm);
String cipherBlockMode = manager.getStringValue(SymmetricDecryptionBlockCipherMode);
String padding = manager.getStringValue(SymmetricDecryptionPadding);
// Key bytes are only the first 16 bytes
final int KEY_BYTES_STARTING_BYTE = 0;
final int KEY_BYTES_ENDING_BYTE = 16;
// IV bytes are only the first 16 bytes
final int IV_BYTES_STARTING_BYTE = 0;
final int IV_BYTES_ENDING_BYTE = 16;
// Cipher bytes are everything after first 16 bytes (iv bytes)
final int CIPHER_BYTES_STARTING_BYTE = IV_BYTES_ENDING_BYTE;
try {
// 1. Get the cipher ready to start doing the AES transformation
Cipher cipher = Cipher.getInstance(decryptionAlgorithm + "/" + cipherBlockMode + "/" + padding);
// 2. Only take the first 16 bytes so that it is 128 bits as we are doing AES 128 bit decryption
// *Note: if this is not 128 bit decryption then you might have to change this ...
byte[] trimmedKeyBytes = Arrays.copyOfRange(keyBytes, KEY_BYTES_STARTING_BYTE, KEY_BYTES_ENDING_BYTE);
// 3. Start the decryption process by creating a key spec object
SecretKeySpec keySpec = new SecretKeySpec(trimmedKeyBytes, decryptionAlgorithm);
// 4. The initialization vector (IV) is the first 16 bytes/octets of the cipher value in the body.
// 4.1 To recover the IV, Base64 decode the CipherValue
byte[] cipherBytes = Base64.decodeBase64(encryptedAttachmentBytes);
// 4.2 The remainder after the first 16 bytes is the encrypted message
// -do +2 from start because we want to remove \r\n at the beginning and -2 to remove \r\n from the end
// Remove the new line and carriage returns from beginning and end, if they are there
byte[] encryptedBytes = null;
byte[] ivBytes = null;
if( encryptedAttachmentBytes[0] == '\r' &&
encryptedAttachmentBytes[1] == '\n' &&
encryptedAttachmentBytes[encryptedAttachmentBytes.length-2] == '\r' &&
encryptedAttachmentBytes[encryptedAttachmentBytes.length-1] == '\n') {
encryptedBytes = Arrays.copyOfRange(encryptedAttachmentBytes, CIPHER_BYTES_STARTING_BYTE + 2, encryptedAttachmentBytes.length - 2);
// 4.2a And take bytes 2 thru 18 instead of 0 thru 16 to account for extra \r \n's
ivBytes = Arrays.copyOfRange(encryptedAttachmentBytes, IV_BYTES_STARTING_BYTE + 2, IV_BYTES_ENDING_BYTE + 2);
}else{
encryptedBytes = Arrays.copyOfRange(encryptedAttachmentBytes, CIPHER_BYTES_STARTING_BYTE, encryptedAttachmentBytes.length);
// 4.2b And take the first 16 bytes from encrypted text to get the IV bytes
ivBytes = Arrays.copyOfRange(encryptedAttachmentBytes, IV_BYTES_STARTING_BYTE, IV_BYTES_ENDING_BYTE);
}
// 5. Create the IV Parameter spec from the ivBytes obtained above
IvParameterSpec iv = new IvParameterSpec(ivBytes);
// 6. Initialize the cipher using the key spec and iv we just initialized
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
// 7. Finish the decryption process
decryptedValue = cipher.doFinal(encryptedBytes);
} catch (Exception e) {
System.err.println("Exception occurred in symmetricDecryptAttachment() of SOAPDecryptionProcessor: \n" + e.getMessage());
throw new EIPException(e.getMessage());
}
return decryptedValue;
}发布于 2020-03-04 01:09:48
String decryptionAlgorithm = manager.getStringValue(SymmetricDecryptionAlgorithm);这是什么管理器,为什么方法必须执行自己的配置?
// Key bytes are only the first 16 bytes
final int KEY_BYTES_STARTING_BYTE = 0;
final int KEY_BYTES_ENDING_BYTE = 16;
final int IV_BYTES_STARTING_BYTE = 0;
final int IV_BYTES_ENDING_BYTE = 16;完全不需要,如果它们是,它们应该是private static类变量,这是Java常量的等价物。那么使用Cipher#getBlockSize()呢?
// 1. Get the cipher ready to start doing the AES transformation
Cipher cipher = Cipher.getInstance(decryptionAlgorithm + "/" + cipherBlockMode + "/" + padding);这个注释是危险的,因为它提到了AES,但是您配置了decryptionAlgorithm。我不知道为什么为此需要3个单独的配置字段。
byte[] trimmedKeyBytes = Arrays.copyOfRange(keyBytes, KEY_BYTES_STARTING_BYTE, KEY_BYTES_ENDING_BYTE);那么,如果用户提供了一个256位的密钥,那么只需使用128位而不抛出错误?这根本不是什么好做法。
byte[] encryptedBytes = null;
byte[] ivBytes = null;您已经在if语句中分配引用,无需将它们初始化为null。您甚至可以将它们设置为final,以便您知道每个分支都将初始化变量!
// -do +2 from start because we want to remove \r\n at the beginning and -2 to remove \r\n from the end
// Remove the new line and carriage returns from beginning and end, if they are there您有二进制数据,它已经被64位解码,而您原来的二进制密文可能包含一个回车+行提要?嗯,随机的IV或密文可能包含的概率为1/65536,这意味着你的解密将失败约40亿次。你只需要等待足够长的时间才能实现。
encryptedBytes = Arrays.copyOfRange(encryptedAttachmentBytes, CIPHER_BYTES_STARTING_BYTE, encryptedAttachmentBytes.length);首先,我不知道你为什么要复制加密的数据,然后是IV字节,因为这根本就没有意义--你从来没有按照这个顺序接收或需要它们。
但是请注意,IvParameterSpec()构造函数和Cipher#doFinal()方法都有表单,允许您定义偏移量和要使用的字节数。对于IV来说,这并不重要,但对于密文来说,这又增加了伤害。
private byte[] symmetricDecryptAttachment(byte[] encryptedAttachmentBytes, byte[] keyBytes) throws IOException, GeneralSecurityException, EIPException {
try {
...
} catch (Exception e) {
System.err.println("Exception occurred in symmetricDecryptAttachment() of SOAPDecryptionProcessor: \n" + e.getMessage());
throw new EIPException(e.getMessage());
}Pokemon异常处理,使用System.out,从堆栈跟踪中删除异常,不指定可以抛出哪些异常,也不区分不同类型的异常(NoSuchAlgorithmException不同于糟糕的密文,对吗?)
这种异常处理必须进行。
请注意,CBC只对机密性有用,然后最好只对经过身份验证的消息或就地加密/解密有用。我不确定您是否在使用GCM,但是使用GCM可能是一个更好的选择(在一个12字节的IV中)。
至于你的问题:是的,使用流。增量更新也是可能的,但考虑到您的密文可能到达每个流,使用CipherInputStream是最有意义的。注意,Base64编码器类也可以包装在流上。
https://codereview.stackexchange.com/questions/152450
复制相似问题