none
java的AES256加密如何转成C# RRS feed

  • 问题

  • 需要用到AES256加密,但是用C#加密出来后跟对方的结果对不上,所以需要把对方提供的原java版本的加密方法转成C#的,对java的代码不太熟悉,请问有人能帮忙转一下吗

    java的代码是:

    package com.dadimedia.hamc;
    import java.io.UnsupportedEncodingException;
    import java.security.InvalidAlgorithmParameterException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.Security;
    import java.security.spec.InvalidKeySpecException;

    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.PBEKeySpec;
    import javax.crypto.spec.SecretKeySpec;

    import org.bouncycastle.jce.provider.BouncyCastleProvider;


    /**
     * AES加解密工具类
     */
    public class AES {
    private static final String KEY_GENERATION_ALG = "PBKDF2WithHmacSHA1";
    private static final int HASH_ITERATIONS = 10000;
    private static final int KEY_LENGTH = 256;
    private static byte[] salt = { 1, 3, 9, 6, 9, 4, 4, 4, 0, 2, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
    private static final String CIPHERMODEPADDING = "AES/CBC/PKCS5Padding";
    private static IvParameterSpec ivSpec = new IvParameterSpec(new byte[] { 0xA, 1, 0xB, 5, 4, 0xF, 7, 9, 0x17, 3, 1, 6, 8, 0xC, 0xD, 91 });
    static {
    Security.addProvider(new BouncyCastleProvider());
    }
    public static void main(String[] args) {
    for (int i = 0; i < 1; i++) {
    String s = "lhdV+wj177YyjirsxeikaNestM/YafgOxrpiGbMVxzvefarFNbQfGHXauqmTIJk+upexqehjv8xK+mlx2SbnDg==" + System.currentTimeMillis();
    String key = "wandayuanxian100008";
    String t = "";
    try {
    t = AES.encrypt(s.getBytes("UTF-8"), key);
    } catch (UnsupportedEncodingException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    try {
    System.out.println(t);
    String de = AES.decrypt(t, key);
    System.out.println(de);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }

    public static SecretKeyFactory createSecretKeyFactory() {
    try {
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance(AES.KEY_GENERATION_ALG);
    return keyfactory;
    } catch (NoSuchAlgorithmException e) {
    System.out.println("no key factory support for PBEWITHSHAANDTWOFISH-CBC");
    }
    return null;

    }

    public static SecretKeySpec aesKeyConvert(String key) {
    try {
    PBEKeySpec myKeyspec = new PBEKeySpec(key.toCharArray(), AES.salt, AES.HASH_ITERATIONS, AES.KEY_LENGTH);
    SecretKeyFactory keyfactory = createSecretKeyFactory();
    SecretKey sk = keyfactory.generateSecret(myKeyspec);
    byte[] skAsByteArray = sk.getEncoded();
    SecretKeySpec skforAES = new SecretKeySpec(skAsByteArray, "AES");
    return skforAES;
    } catch (InvalidKeySpecException ikse) {
    System.out.println("invalid key spec for PBEWITHSHAANDTWOFISH-CBC");
    }
    return null;
    }

    public static String encrypt(byte[] plaintext, String password) {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    SecretKeySpec skforAES = aesKeyConvert(password);
    byte[] ciphertext = encrypt(AES.CIPHERMODEPADDING, skforAES, AES.ivSpec, plaintext);
    // try {
    // System.out.println("加密原串为:" + new String(ciphertext, "UTF-8"));
    // } catch (UnsupportedEncodingException e) {
    // e.printStackTrace();
    // }
    String base64_ciphertext = Base64Encoder.encode(ciphertext);
    return base64_ciphertext;
    }

    public static String decrypt(String ciphertext_base64, String password) {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    byte[] s = Base64Decoder.decodeToBytes(ciphertext_base64);
    SecretKeySpec skforAES = aesKeyConvert(password);
    String decrypted = new String(decrypt(AES.CIPHERMODEPADDING, skforAES, AES.ivSpec, s));
    return decrypted;
    }

    public static String decrypt(byte[] data, String password) {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    SecretKeySpec skforAES = aesKeyConvert(password);
    String decrypted = new String(decrypt(AES.CIPHERMODEPADDING, skforAES, AES.ivSpec, data));
    return decrypted;
    }

    /**
    * 加密

    * @param cmp
    *            填充方式
    * @param sk
    *            密钥
    * @param IV
    *            向量
    * @param msg
    *            需要加密的内容
    * @return 返回加密结果
    */
    public static byte[] encrypt(String cmp, SecretKey sk, IvParameterSpec IV, byte[] msg) {
    try {
    Cipher c = Cipher.getInstance(cmp);
    c.init(Cipher.ENCRYPT_MODE, sk, IV);
    return c.doFinal(msg);
    } catch (NoSuchAlgorithmException e) {
    System.out.println(e.getMessage());
    } catch (NoSuchPaddingException e) {
    System.out.println(e.getMessage());
    } catch (InvalidKeyException e) {
    System.out.println(e.getMessage());
    } catch (InvalidAlgorithmParameterException e) {
    System.out.println(e.getMessage());
    } catch (IllegalBlockSizeException e) {
    System.out.println(e.getMessage());
    } catch (BadPaddingException e) {
    System.out.println(e.getMessage());
    }
    return null;
    }

    /**
    * 解密

    * @param cmp
    *            填充函数
    * @param sk
    *            密钥
    * @param IV
    *            向量
    * @param ciphertext
    *            需要解密内容
    * @return 返回解密结果
    */
    public static byte[] decrypt(String cmp, SecretKey sk, IvParameterSpec IV, byte[] ciphertext) {
    try {
    Cipher c = Cipher.getInstance(cmp);
    c.init(Cipher.DECRYPT_MODE, sk, IV);
    return c.doFinal(ciphertext);
    } catch (NoSuchAlgorithmException nsae) {
    System.out.println(nsae.getMessage());
    } catch (NoSuchPaddingException nspe) {
    System.out.println(nspe.getMessage());
    } catch (InvalidKeyException e) {
    System.out.println(e.getMessage());
    } catch (InvalidAlgorithmParameterException e) {
    System.out.println(e.getMessage());
    } catch (IllegalBlockSizeException e) {
    System.out.println(e.getMessage());
    } catch (BadPaddingException e) {
    System.out.println(e.getMessage());
    }
    return null;
    }
    }

    2018年5月7日 2:17

答案

  • 你好,

    下面的AES方法,你可以参考一下

    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    
    namespace WindowsFormsApp1
    {
        public class AES
        {
            //加密
            public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
            {
                byte[] encryptedBytes = null;
    
                // Set your salt here, change it to meet your flavor:
                // The salt bytes must be at least 8 bytes.
                byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
    
                using (MemoryStream ms = new MemoryStream())
                {
                    using (RijndaelManaged AES = new RijndaelManaged())
                    {
                        AES.KeySize = 256;
                        AES.BlockSize = 128;
    
                        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                        AES.Key = key.GetBytes(AES.KeySize / 8);
                        AES.IV = key.GetBytes(AES.BlockSize / 8);
    
                        AES.Mode = CipherMode.CBC;
    
                        using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                            cs.Close();
                        }
                        encryptedBytes = ms.ToArray();
                    }
                }
    
                return encryptedBytes;
            }
    
            //解密
            public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
            {
                byte[] decryptedBytes = null;
    
                // Set your salt here, change it to meet your flavor:
                // The salt bytes must be at least 8 bytes.
                byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
    
                using (MemoryStream ms = new MemoryStream())
                {
                    using (RijndaelManaged AES = new RijndaelManaged())
                    {
                        AES.KeySize = 256;
                        AES.BlockSize = 128;
    
                        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                        AES.Key = key.GetBytes(AES.KeySize / 8);
                        AES.IV = key.GetBytes(AES.BlockSize / 8);
    
                        AES.Mode = CipherMode.CBC;
    
                        using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                            cs.Close();
                        }
                        decryptedBytes = ms.ToArray();
                    }
                }
    
                return decryptedBytes;
            }
    
            //加密字符串
            public string EncryptText(string input, string password)
            {
                // Get the bytes of the string
                byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
    
                // Hash the password with SHA256
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
    
                byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
    
                string result = Convert.ToBase64String(bytesEncrypted);
    
                return result;
            }
    
            //解密字符串
            public string DecryptText(string input, string password)
            {
                // Get the bytes of the string
                byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
    
                byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);
    
                string result = Encoding.UTF8.GetString(bytesDecrypted);
    
                return result;
            }
    
            //加密文件
            public void EncryptFile()
            {
                string file = "C:\\SampleFile.DLL";
                string password = "abcd1234";
    
                byte[] bytesToBeEncrypted = File.ReadAllBytes(file);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
    
                // Hash the password with SHA256
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
    
                byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
    
                string fileEncrypted = "C:\\SampleFileEncrypted.DLL";
    
                File.WriteAllBytes(fileEncrypted, bytesEncrypted);
            }
    
            //解密文件
            public void DecryptFile()
            {
                string fileEncrypted = "C:\\SampleFileEncrypted.DLL";
                string password = "abcd1234";
    
                byte[] bytesToBeDecrypted = File.ReadAllBytes(fileEncrypted);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
    
                byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);
    
                string file = "C:\\SampleFile.DLL";
                File.WriteAllBytes(file, bytesDecrypted);
            }
        }
    }
    

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2018年5月8日 6:55
    版主

全部回复

  • 你好,

    你可以使用一些在线的转换工具在转换一下。 比如下面的网站:

    https://www.carlosag.net/tools/codetranslator/

    注意:此回答中包含对第三方万维网站点的引用。微软提供这些信息是为了方便你。

    微软不控制这些网站,也没有测试在这些网站上发现的任何软件或信息;因此,微软不能就在那里发现的任何软件或信息的质量、安全性或适用性作出任何陈述。

    使用任何在互联网上找到的软件都存在固有的危险,微软提醒你在从互联网上检索任何软件之前,要确保你完全了解风险。

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2018年5月7日 5:45
    版主
  • 感谢答复,但貌似并没有什么用啊,只是单纯把import 换成了using而已,用到的方法并没有变化


    2018年5月7日 6:02
  • 你好,麻烦能否提供一个标准的C#的aes256加密的类库,然后我再把相关参数改成原java版的

    网上找的各式各样的C# aes256加密的类不知道哪个是正确的。

    2018年5月8日 6:42
  • 你好,

    下面的AES方法,你可以参考一下

    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    
    namespace WindowsFormsApp1
    {
        public class AES
        {
            //加密
            public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
            {
                byte[] encryptedBytes = null;
    
                // Set your salt here, change it to meet your flavor:
                // The salt bytes must be at least 8 bytes.
                byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
    
                using (MemoryStream ms = new MemoryStream())
                {
                    using (RijndaelManaged AES = new RijndaelManaged())
                    {
                        AES.KeySize = 256;
                        AES.BlockSize = 128;
    
                        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                        AES.Key = key.GetBytes(AES.KeySize / 8);
                        AES.IV = key.GetBytes(AES.BlockSize / 8);
    
                        AES.Mode = CipherMode.CBC;
    
                        using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                            cs.Close();
                        }
                        encryptedBytes = ms.ToArray();
                    }
                }
    
                return encryptedBytes;
            }
    
            //解密
            public byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
            {
                byte[] decryptedBytes = null;
    
                // Set your salt here, change it to meet your flavor:
                // The salt bytes must be at least 8 bytes.
                byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
    
                using (MemoryStream ms = new MemoryStream())
                {
                    using (RijndaelManaged AES = new RijndaelManaged())
                    {
                        AES.KeySize = 256;
                        AES.BlockSize = 128;
    
                        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                        AES.Key = key.GetBytes(AES.KeySize / 8);
                        AES.IV = key.GetBytes(AES.BlockSize / 8);
    
                        AES.Mode = CipherMode.CBC;
    
                        using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                            cs.Close();
                        }
                        decryptedBytes = ms.ToArray();
                    }
                }
    
                return decryptedBytes;
            }
    
            //加密字符串
            public string EncryptText(string input, string password)
            {
                // Get the bytes of the string
                byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
    
                // Hash the password with SHA256
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
    
                byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
    
                string result = Convert.ToBase64String(bytesEncrypted);
    
                return result;
            }
    
            //解密字符串
            public string DecryptText(string input, string password)
            {
                // Get the bytes of the string
                byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
    
                byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);
    
                string result = Encoding.UTF8.GetString(bytesDecrypted);
    
                return result;
            }
    
            //加密文件
            public void EncryptFile()
            {
                string file = "C:\\SampleFile.DLL";
                string password = "abcd1234";
    
                byte[] bytesToBeEncrypted = File.ReadAllBytes(file);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
    
                // Hash the password with SHA256
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
    
                byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
    
                string fileEncrypted = "C:\\SampleFileEncrypted.DLL";
    
                File.WriteAllBytes(fileEncrypted, bytesEncrypted);
            }
    
            //解密文件
            public void DecryptFile()
            {
                string fileEncrypted = "C:\\SampleFileEncrypted.DLL";
                string password = "abcd1234";
    
                byte[] bytesToBeDecrypted = File.ReadAllBytes(fileEncrypted);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
    
                byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);
    
                string file = "C:\\SampleFile.DLL";
                File.WriteAllBytes(file, bytesDecrypted);
            }
        }
    }
    

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2018年5月8日 6:55
    版主
  • 好的,谢谢。

    已经让人帮忙用原来的java转出C#了。

    感谢帮忙啊。

    2018年5月9日 7:34