【问题标题】:AES CTR Mode with Bouncycastle Cryptography带有 Bouncycastle 加密的 AES CTR 模式
【发布时间】:2012-12-04 20:05:59
【问题描述】:

我正在尝试使用Bouncy castle cryptography library in C# 来实现 AES CTR 加密。 .NET 提供了RijndaelManaged Crypto Library,但它不支持 AES 的 CTR 模式,因此选择了 Bouncycastle。

我无法正确编码问题似乎出在 IV 上。

    public string BytesToHex(byte[] bytes)
    {
        char[] c = new char[bytes.Length * 2];

        byte b;

        for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx)
        {
            b = ((byte)(bytes[bx] >> 4));
            c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);

            b = ((byte)(bytes[bx] & 0x0F));
            c[++cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
        }

        return new string(c);
    }

    public byte[] HexToBytes(string str)
    {
        if (str.Length == 0 || str.Length % 2 != 0)
            return new byte[0];

        byte[] buffer = new byte[str.Length / 2];
        char c;
        for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
        {
            // Convert first half of byte
            c = str[sx];
            buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0')) << 4);

            // Convert second half of byte
            c = str[++sx];
            buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0'));
        }

        return buffer;
    }
   private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
    {
        int minSize = cipher.GetOutputSize(data.Length);
        byte[] outBuf = new byte[minSize];
        int length1 = cipher.ProcessBytes(data, 0, data.Length, outBuf, 0);
        int length2 = cipher.DoFinal(outBuf, length1);
        int actualLength = length1 + length2;
        byte[] result = new byte[actualLength];
        Array.Copy(outBuf,result,actualLength);

        //System.arraycopy(outBuf, 0, result, 0, result.length);
        return result;
    }
    private static byte[] decryptCTR(byte[] cipher, byte[] key, byte[] iv)
    {
        //Org.BouncyCastle.Crypto.Modes.SicBlockCipher

      PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new SicBlockCipher(new AesEngine()));

      ParametersWithIV   ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
      aes.Init(false, ivAndKey);

      return cipherData(aes, cipher);
    }
    private static byte[] encryptCTR(byte[] plain, byte[] key, byte[] iv)
    {
        PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new SicBlockCipher(
                new AesEngine()));

        ParametersWithIV ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
        aes.Init(true, ivAndKey);
        return cipherData(aes, plain);
    }

我正在尝试使用以下方法解密给定的密文

   private void btnDecryptDirectly_Click(object sender, EventArgs e)
    {
        String encodedMsgHex =  "770b80259ec33beb2561358a9f2dc617e46218c0a53cbeca695ae45faa8952aa0e311bde9d4e01726d3184c34451";
        String key = "36f18357be4dbd77f050515c73fcf9f2";
        byte [] keyBytes = HexToBytes(key);

        byte[] cipher = HexToBytes(encodedMsgHex);

        txtDecryptedText = BytesToHex(decryptCTR(cipher, keyBytes, IV));

        rtbDecrypted.Text = txtDecryptedText;
    }

每次运行都会出错

最后一个块解密不完整

错误。

谁能帮帮我。

【问题讨论】:

  • owlstead 关于不需要填充是正确的。我建议使用 CipherUtilities.GetCipher("AES/CTR/NoPadding") 来获取密码对象,至少在你有基本工作之前。您可能还会发现 Org.BouncyCastle.Utilities.Encoders.Hex 类很有用。

标签: c# cryptography aes bouncycastle rijndaelmanaged


【解决方案1】:

您根本不需要使用PaddedBufferedBlockCipher。计数器模式加密是分组密码的流模式。流式密码不需要填充。

您可以使用BufferedBlockCipher 访问流模式,因为SicBlockCipher 一次只能加密一个块。

【讨论】:

  • SicBlockCipher 的 C# 实现似乎只提供了 ProcessBlock,没有提供 processbytes。
  • @Sentinel 谢谢,已修复。
  • Quick q 从我这里开始,因为我一直在试图理解一些 java 代码如何用于 c# 端口.... Java 中的 SicBlockCipher 似乎允许直接处理单个字节到输出缓冲区,但如果不调用 DoFinal,BufferedBlockCipher 似乎不会做同样的事情。我的理解正确吗?如果你愿意,我可以把它放到一个 SO 问题中。
  • 请创建一个问题,它似乎对其他人也很有用!
  • OK 在这里添加 stackoverflow.com/questions/51286633/… 任何帮助,非常感谢。
【解决方案2】:

如果您只需要 CTR 模式,您可以轻松地自己编写代码 - 它只需将 IV、IV + 1、IV + 2、IV +3 ... 写入缓冲区(最多输入数据大小),加密此缓冲区,并与需要加密或解密的缓冲区进行异或运算。 这可以通过内置的 Rijndael Managed 来实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-09
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    相关资源
    最近更新 更多