【问题标题】:C# / Java | AES256 encrypt/decryptC#/Java | AES256 加密/解密
【发布时间】:2012-03-06 12:57:38
【问题描述】:

我想加密通过 Java/C# 套接字(Java 服务器、C# 客户端)发送的所有数据。 我想使用 AES256,但我无法让 Java 和 C# 生成相同的加密代码。谁能给我两个例子,1 个 Java 和 1 个 C# 生成相同的结果并正确解密结果?

到目前为止我尝试了什么:

public Encrypt(AOBCore instance){
    try {
        String message="This is just an example";

           // Get the KeyGenerator

           KeyGenerator kgen = KeyGenerator.getInstance("AES");
           kgen.init(256); // 192 and 256 bits may not be available


           // Generate the secret key specs.
           SecretKey skey = kgen.generateKey(); //Cantget 'test' in here...
           byte[] raw = skey.getEncoded();

           SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");


           // Instantiate the cipher

           Cipher cipher = Cipher.getInstance("AES");

           cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

           byte[] encrypted =
             cipher.doFinal(message.getBytes());
           System.out.println("encrypted string: " + asHex(encrypted));

           cipher.init(Cipher.DECRYPT_MODE, skeySpec);
           byte[] original =
             cipher.doFinal(encrypted);
           String originalString = new String(original);
           System.out.println("Original string: " +
             originalString + " " + asHex(original));
    } catch (Exception e) {
        instance.logMessage(e.getMessage());
    }
}

public static String asHex (byte buf[]) {
      StringBuffer strbuf = new StringBuffer(buf.length * 2);
      int i;

      for (i = 0; i < buf.length; i++) {
       if (((int) buf[i] & 0xff) < 0x10)
        strbuf.append("0");

       strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
      }

      return strbuf.toString();
     }

}

static void Main(string[] args)
    {
        while (true)
        {
            var plain = Console.ReadLine();
            var key = GenerateKey(256);
            var encoded = Encrypt(plain, key, 256);
            Console.WriteLine("Encoded: " + encoded);
            Console.WriteLine(Decrypt(encoded, key, 256));
        }
    }

    private static string GenerateKey(int keySize)
    {
        return "test";
    }

    private static string Encrypt(string plainStr, string completeEncodedKey, int keySize)
    {
        RijndaelManaged aesEncryption = new RijndaelManaged();
        aesEncryption.KeySize = keySize;
        aesEncryption.BlockSize = 256;
        aesEncryption.Mode = CipherMode.CBC;
        aesEncryption.Padding = PaddingMode.PKCS7;
        aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);
        aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]);
        byte[] plainText = ASCIIEncoding.UTF8.GetBytes(plainStr);
        ICryptoTransform crypto = aesEncryption.CreateEncryptor();
        // The result of the encryption and decryption            
        byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length);
        return Convert.ToBase64String(cipherText);
    }

    private static string Decrypt(string encryptedText, string completeEncodedKey, int keySize)
    {
        RijndaelManaged aesEncryption = new RijndaelManaged();
        aesEncryption.KeySize = keySize;
        aesEncryption.BlockSize = 128;
        aesEncryption.Mode = CipherMode.CBC;
        aesEncryption.Padding = PaddingMode.PKCS7;
        aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);
        aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]);
        ICryptoTransform decrypto = aesEncryption.CreateDecryptor();
        byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length);
        return ASCIIEncoding.UTF8.GetString(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length));
    }

【问题讨论】:

  • 你应该展示你迄今为止所做的尝试——这不是一个代码工厂,互联网提供了大量的例子。
  • 添加了我尝试过的内容...不,我找不到很多关于 C#/Java 示例的信息。
  • 看来你也有同样的问题stackoverflow.com/q/5295110/55209
  • 确实如此。使用该代码,我得到 uZ▀pE÷R~JÙ‗(tÄÒ$f6~∟\¸¸(À}5ÒZêL♣ 并通过 testtesttesttest 并通过 testtesttesttest。我猜这是不对的:P

标签: c# java encryption aes


【解决方案1】:

问题在于您没有在 Java 代码中指定密码模式或填充。这将使用算法默认值,当需要与其他库的互操作性时,这绝不是您想要做的事情。像这样初始化你的Cipher

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

根据this 的回答,Java 中的 PKCS5 应该与 .Net 中的 PKCS7 兼容。由于您明智地使用 CBC,您将需要修改代码以使用相同的初始化向量进行加密和解密。您应该为此使用密钥。 IV应该是随机生成的。您可以通过调用cipher.getIV() 来使用Java Cipher 生成的IV 进行加密。

此外,请注意与 cmets 中提到的字符编码保持一致。

【讨论】:

    猜你喜欢
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    相关资源
    最近更新 更多