C#/ Java | AES256加密/解密 [英] C# / Java | AES256 encrypt/decrypt

查看:177
本文介绍了C#/ Java | AES256加密/解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想加密通过Java / C#套接字(Java服务器,C#客户端)发送的所有数据。
我想使用AES256,但是我不能得到Java和C#来生成相同的加密代码。任何人都可以给我两个例子,1个在Java中,1个在C#中生成相同的结果,并正确解密结果?



我迄今为止所尝试的:

  public Encrypt(AOBCore instance){
try {
String message =这只是一个例子;

//获取KeyGenerator

KeyGenerator kgen = KeyGenerator.getInstance(AES);
kgen.init(256); // 192和256位可能不可用


//生成秘密密钥规范。
SecretKey skey = kgen.generateKey(); // Cantget'test'in here ...
byte [] raw = skey.getEncoded();

SecretKeySpec skeySpec = new SecretKeySpec(raw,AES);


//实例化密码

密码密码= 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;对于(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));
}
}

私有静态字符串GenerateKey(int keySize)
{
returntest;
}

private static string Encrypt(string plainStr,string fullyEncodedKey,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();
//加密和解密的结果
byte [] cipherText = crypto.TransformFinalBlock(plainText,0,plainText.Length);
return Convert.ToBase64String(cipherText);
}

private static string Decrypt(string encryptedText,string fullyEncodedKey,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);
返回ASCIIEncoding.UTF8.GetString(decrypto.TransformFinalBlock(encryptedBytes,0,encryptedBytes.Length));
}


解决方案

问题是你是不要在Java代码中指定密码或填充。这将使用算法默认值,当需要与其他库的互操作性时,这绝对不是您想要执行的操作。初始化密码,如下所示:

 加密密码= Cipher.getInstance AES / CBC / PKCS5Padding); 

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

另外,注意与注释中提到的字符编码一致。


I want to encrypt all the data I send through the Java/C# sockets (Java server, C# client). I would like to use AES256, but I can't get the Java and C# to generate the same encrypted code. Can anyone give me two examples, 1 in Java and 1 in C# that generate the same results and decrypts the results properly?

What I tried so far:

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));
    }

解决方案

The problem is that you aren't specifying the ciphermode or the padding in the Java code. This will use the algorithm defaults, which is never something you want to do when interoperability with other libraries is required. Initialize your Cipher like this:

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

PKCS5 in Java should be compatible with PKCS7 in .Net according to this answer. Since you are wisely using CBC you are going to need to modify the code to use the same initialization vector for both encryption and decryption. You should NOT use the secret key for that. The IV should be randomly generated. You can use the IV that the Java Cipher generated for encryption by calling cipher.getIV().

Also, take care to be consistent with character encodings as has been mentioned in the comments.

这篇关于C#/ Java | AES256加密/解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆