C#/ Java | AES256加密/解密

时间:2012-03-06 12:57:38

标签: c# java encryption aes

我想加密通过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));
    }

1 个答案:

答案 0 :(得分:4)

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

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

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

另外,请注意与评论中提到的字符编码保持一致。