【问题标题】:AES Encryption adds junk character in BlackberryAES 加密在黑莓中添加了垃圾字符
【发布时间】:2013-07-25 08:58:06
【问题描述】:

我有一个问题。在我的应用程序中,我使用 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();
}

请注意,我无权访问服务器上的解密逻辑。

【问题讨论】:

  • 像 AES 这样的分组密码需要填充。加密数据比原始数据长是绝对正常的。我认为你根本不需要在客户端做任何事情。
  • 服务器端的人显然不知道如何处理加密/解密。您可能希望向组织中的合适人员表明这一点。他们的所作所为完全不安全。

标签: java encryption blackberry aes


【解决方案1】:

我不完全清楚您是在服务器端解密,还是仅仅因为字节数比原始数据多而称它们为垃圾字符。如果它总是添加 16 个或更少的字节,那么这就是 PKCS5 填充,用于使您的数据可被密码的块大小整除。解密后看不到,因为解密器会自动剥离pad。

但是,查看 Blackberry 文档,我建议您更改加密,因为 BlockEncryptor 默认为 ECB 模式。这是一个mode of operation,它很容易泄露有关明文的信息。相反,请选择 BlockEncryptor 的子类,例如 CBCEncryptorEngine。您需要将 IV 与您的密文一起传输,以便稍后在此模型中进行解密。

在使用 Blackberry 提供的结构实现加密时要非常非常小心。很容易出错(比如使用 ECB),生成的密文可能看起来很好,但从根本上被破坏了。

【讨论】:

  • 但我应该使用 ECB 模式,因为在服务器端使用 ECB 模式.. 你能帮我在黑莓中加密数据时如何删除垃圾字符吗?
  • 如果您对服务器端有任何控制权,请更改它。 ECB 不是安全模式。如果你没有控制权,问题很可能是服务器端的解密不理解填充。如果您查看最后一个字节的值,您可以自己剥离它。假设它是 PKCS5/PKCS7 填充,那么无论该字节的整数表示是什么,都会告诉您要剥离的字节数。例如,03 意味着应该去除最后 3 个字节(所有 3 个字节的值都是 03)。
  • 来自 Android 和 J2ME 的加密数据可以从服务器端完美解密,除了黑莓。所以在服务器端我们不能改变解密的逻辑..所以我不明白什么是问题和应该做什么..?
  • 请在您的问题中编辑此类信息。我起草了一个答案,但当我重新阅读保罗的答案时才发现这个特别的评论。
【解决方案2】:

问题当然可能出在您没有显示的解密代码中。您很可能在解密期间没有使用padding mode。因此,填充字符被视为纯文本。它们可能包含字节值,例如:

01
0202
030303

这被称为PKCS#5 padding or PKCS#7 padding。它已由您在加密期间指定 (PKCS5FormatterEngine)。

这些应该在解密后在服务器端删除。如果可能,请使用库来执行此操作。始终添加 PKCS#5 填充,因此也可以自己删除填充字节非常简单。不可打印字符


正如您在对答案的评论中指出的那样,如果您无法更改服务器端,那么您应该将客户端更改为使用零字节填充。这只是向纯文本添加零字节,直到您可以将纯文本除以块大小。您可能必须手动执行此操作。似乎服务器端只是简单地解密纯文本,然后它可能使用以空结尾的字符串,或者它“修剪”纯文本,删除任何空格(包括终止字符)。然后加密,但当然不使用PKCS5FormatterEngine


请注意,PKCS#5 和零字节填充都不会增加真实性或完整性,如果您使用带有这种填充的 ECB/CBC 加密,那么您很可能容易受到padding oracle attacks 的攻击。每字节明文 128 次尝试检索明文。

【讨论】:

  • 让我猜猜,您在服务器端使用 PHP...它不包含 PKCS#5 填充。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多