我有一个问题。在我的应用程序中,我使用的是AES加密和解密。当我加密数据并将其发送到服务器端时,它会显示一些添加到加密数据的垃圾字符。但是如何?
实际上,这个加密数据是从我这边完全解密的,但服务器收到时会有垃圾字符。
这是我的加密代码:
public static byte[] encrypt( byte[] keyData, byte[] data )
throws CryptoException, IOException
{
// Create the AES key to use for encrypting the data.
// This will create an AES key using as much of the keyData
// as possible.
AESKey key = new AESKey( keyData );
// Now, we want to encrypt the data.
// First, create the encryptor engine that we use for the actual
// encrypting of the data.
AESEncryptorEngine engine = new AESEncryptorEngine( key );
// Since we cannot guarantee that the data will be of an equal block
// length we want to use a padding engine (PKCS5 in this case).
PKCS5FormatterEngine fengine = new PKCS5FormatterEngine( engine );
// Create a BlockEncryptor to hide the engine details away.
ByteArrayOutputStream output = new ByteArrayOutputStream();
BlockEncryptor encryptor = new BlockEncryptor( fengine, output );
encryptor.write( data );
encryptor.close();
output.close();
return output.toByteArray();
}
请注意,我无法访问服务器上的解密逻辑。
答案 0 :(得分:3)
我不清楚你是在服务器端进行解密,还是因为字节数比原始数据多,所以你称之为垃圾字符。如果它总是添加16个或更少的字节,那么这就是PKCS5填充,用于使数据可以被密码的块大小整除。解密后它不可见,因为解密器会自动剥离打击垫。
但是,查看Blackberry文档,我建议您更改加密,因为BlockEncryptor默认为ECB模式。这是一个mode of operation,很容易泄漏有关明文的信息。相反,选择BlockEncryptor的子类,例如CBCEncryptorEngine。您需要在此模型中稍后将IV与密文一起传输以进行解密。
使用Blackberry提供的结构实现加密时非常非常小心。它很容易出错(比如使用ECB),并且由此产生的密文在从根本上被打破时可能看起来很好。
答案 1 :(得分:0)
问题可能在于解密代码,当然没有显示。您可能在解密期间未使用padding mode。因此,填充字符被视为纯文本。它们可能包含字节值,例如:
01
0202
030303
这称为PKCS#5 padding or PKCS#7 padding。您在加密期间已指定它(PKCS5FormatterEngine
)。
解密后应在服务器端删除这些内容。如果可能,请使用库来执行此操作。总是添加PKCS#5填充,因此自己删除填充字节非常简单。不可打印的字符
正如您在答案评论中指出的那样,如果您无法更改服务器端,则应更改客户端以使用零字节填充。这只是简单地向纯文本添加零字节,直到您可以将纯文本除以块大小。这可能你需要手动完成。似乎服务器端只是解密纯文本,然后它可能使用空终止字符串,或者它“修剪”纯文本,删除任何空格(包括终止字符)。然后加密,但当然不使用PKCS5FormatterEngine
。
请注意,PKCS#5和零字节填充不会增加真实性和完整性,如果您使用这种填充的ECB / CBC加密,那么您可能容易受到padding oracle attacks的攻击。每个明文字节以128次尝试检索纯文本。