繁体   English   中英

为什么使用 BouncyCastle 解密的文本与输入文本有点不同?

[英]Why with BouncyCastle decrypted text is a bit different from input text?

我在 Google 上找到了用于加密/解密 Java 中的字符串的代码:

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    byte[] input = "test".getBytes();
    byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
        0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };

    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");

    System.out.println(new String(input));

    // encryption pass
    cipher.init(Cipher.ENCRYPT_MODE, key);

    byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
    int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
    ctLength += cipher.doFinal(cipherText, ctLength);
    System.out.println(new String(cipherText));
    System.out.println(ctLength);

    // decryption pass
    cipher.init(Cipher.DECRYPT_MODE, key);
    byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
    int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
    ptLength += cipher.doFinal(plainText, ptLength);
    System.out.println(new String(plainText));
    System.out.println(ptLength);

这是 output (截图因为我不能复制粘贴一些字符): output screenshot

我的问题是:为什么第一个输入“测试”与第二个(解密的)“测试”不同? 我需要此代码来加密密码并将其保存在 TXT 文件中,然后从 TXT 文件中读取此加密密码并对其进行解密。但是如果这两个输出不同,我将无法执行此操作。 第二个问题:是否可以排除“;” 从加密的文本? 有人能帮助我吗? 谢谢!

如果您阅读getOutputSize()的文档,那么您将看到它返回预期的最大明文量。 cipher实例无法知道添加了多少填充,因此它猜测很高。 当您使用 ECB 或 CBC 模式(或任何其他非流模式)时,您必须调整字节数组的大小。

System.out.println(ctLength);

如您所见, ctLength确实具有正确的大小。 使用Arrays.copyOf(plainText, ptLength)获取正确的字节数,或者使用四参数String构造函数( new String(plainText, 0, ptLength, StandardCharsets.UTF_8) ),以防您只对字符串感兴趣。

密文由随机字符组成。 它实际上取决于您在屏幕上看到的标准字符集。 如果你真的需要文本,那么你可以对密文进行base 64编码。


ECB 模式加密不适合加密字符串。 您应该尝试使用不同的模式,包括设置/存储 IV。

我会使用new String(StandardCharsets.UTF_8)String#getBytes(StandardCharsets.UTF_8)来转换字符串。 如果您不指定字符集,则它使用系统默认字符集,这意味着解密您的密码将无法在所有系统上工作。 The allowed characters also differ with Linux & Android defaulting on UTF-8 while Java SE on Windows (still?) defaults to the Windows-1252 (extended Western-Latin) character set.

绝对不需要使用 Bouncy Castle 提供程序进行 AES 加密(兼容的填充字符串是"PKCS5Padding" )。


请不要从 Google 获取随机代码示例。 在开始实施之前,您需要了解密码学。 不幸的是,您获取安全代码示例的机会几乎为零。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM