C# AES256CBC PBKDF2 迭代盐 SHA256 SHA512加密 可与CryptoJS互通

PBKDF计算使用的是Jither.PBKDF2库 github地址:https://github.com/Anti-weakpasswords/PBKDF2-CSharp-DeriveBytes-custom-A

这个库支持.NET Framework 4.5.1.即Unity可用

可与javascripts的CryptoJS互通与以下api调用效果一致

CryptoJS.lib.WordArray.random(xxx);

CryptoJS.PBKDF2(xxx, xxx, { hasher: CryptoJS.algo.xxx, keySize: xx, iterations: xxxx });

CryptoJS.AES.encrypt(xxx, xxx, {iv: xxx});

0.需要的引用

using System;
using System.Text;
using System.Security.Cryptography;
using Jither.PBKDF2;

1.生成随机盐

    /// <summary>
    /// 生成随机的Hash值
    /// </summary>
    /// <param name="length">Hash的长度</param>
    /// <returns></returns>
    private Byte[] GenerateRandomHash(Int32 length)
    {
        Byte[] tempByte = new byte[length];
        RandomNumberGenerator.Create().GetBytes(tempByte);
        return tempByte;
    }

将字节数组哈希转换为HEX字符串

    /// <summary>
    /// 将字节数组哈希转换为HEX字符串
    /// </summary>
    /// <param name="hash">Hash byte</param>
    /// <returns>16进制的字符串</returns>
    private string HashBytesToHexString(Byte[] hash)
    {
        var hex = new StringBuilder(hash.Length * 2);
        foreach (var b in hash)
            hex.AppendFormat("{0:x2}", b);
        return hex.ToString();
    }

2. PBKDF2迭代密钥(需要其他HMAC修改HMACPseudoRandomFunction<HMACSHAXXX>()即可支持SHA1、SHA256、SHA512)

  /// <summary>
    /// 隐藏密钥
    /// </summary>
    /// <param name="password">密钥</param>
    /// <param name="salt">盐</param>
    /// <param name="iteration">迭代次数</param>
    /// <returns></returns>
    private Byte[] PBKDF2DeriveBytes(Byte[] password, Byte[] salt,Int32 iteration)
    {
        using (var prf = new HMACPseudoRandomFunction<HMACSHA256>(password))
        {
            using (var hash = new PBKDF2DeriveBytes(prf, salt, iteration))
            {
               return hash.GetBytes(32);
            }
        }
    }

 3.AES256CBC加密内容

    /// <summary>
    /// AES 256 CBC 加密
    /// </summary>
    /// <param name="encryptStr">内容</param>
    /// <param name="key">密钥</param>
    /// <param name="iv">偏移</param>
    /// <returns></returns>
    private string AESEncrypt(String encryptStr, Byte[] key, Byte[] iv)
    {
        var aes = new System.Security.Cryptography.AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 256;
        aes.FeedbackSize = 128;
        aes.Key = key;
        aes.IV = iv;
        aes.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
        aes.Mode = System.Security.Cryptography.CipherMode.CBC;
        var crypto = aes.CreateEncryptor(aes.Key, aes.IV);
        byte[] encrypted = crypto.TransformFinalBlock(new UTF8Encoding(false).GetBytes(encryptStr), 0, System.Text.Encoding.UTF8.GetBytes(encryptStr).Length);
        crypto.Dispose();
        return System.Convert.ToBase64String(encrypted);
    }

4.AES256CBC解密

    /// <summary>  
    /// AES解密
    /// </summary>  
    /// <param name="decryptStr">密文</param>  
    /// <param name="key">密钥</param>
    /// <param name="iv">偏移</param>  
    /// <returns></returns>  
    protected string AESDecrypt(String decryptStr, Byte[] key, Byte[] iv)
    {
        var aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 256;
        aes.FeedbackSize = 128;
        aes.Key = key;
        aes.IV = iv;
        aes.Padding = PaddingMode.PKCS7;
        aes.Mode = CipherMode.CBC;
        var crypto = aes.CreateDecryptor(aes.Key, aes.IV);
        byte[] decrypted = crypto.TransformFinalBlock(
            System.Convert.FromBase64String(decryptStr), 0, System.Convert.FromBase64String(decryptStr).Length);
        crypto.Dispose();
        return Encoding.UTF8.GetString(decrypted);
    }

5.验证

    /// <summary>
    /// 验证
    /// </summary>
    void Verification()
    {
        String content = "这里写需要加密的内容";
        String passwordStr = "&!_password_110_112_@_*";
        Byte[] passwordByte = Encoding.UTF8.GetBytes(passwordStr);
        Byte[] saltByte = GenerateRandomHash(128);
        Byte[] ivByte = GenerateRandomHash(16);
        Byte[] keyByte = PBKDF2DeriveBytes(passwordByte, saltByte, 5000);
        String keyStr = HashBytesToHexString(keyByte);
        String encryptContent = AESEncrypt(content, keyByte, ivByte);
        Debug.Log("salt: " + HashBytesToHexString(saltByte));
        Debug.Log("iv: " + HashBytesToHexString(ivByte));
        Debug.Log("key: " + keyStr);
        Debug.Log("加密后的内容: " + encryptContent);
        Byte[] key = PBKDF2DeriveBytes(passwordByte, saltByte, 5000);
        if (HashBytesToHexString(key) == keyStr)
        {
            Debug.Log("验证key正确");
        }
        else
        {
            Debug.Log("验证key失败");
            return;
        }
        String decryptContent = AESDecrypt(encryptContent, key, ivByte);
        Debug.Log("解密后的内容: " + decryptContent);
    }

6.输出结果: 

salt:3aa40a5641ec40e23c9d10b6d75aebb1cf4cb04aba76e854f88a198a66c96fd42cc30e1ad2f0be2aa7242eb7a0a4b6e4460a28fd09aea56dcae8da97e019582aef1c0d1e525ac75ce1bec95fc44dd308f06038cdf8aff7a867f171d61244fd10c35c3600e885a53070e33a82c47db0b8992cfe09c8c1ec6fc39f6f08e0aad192

iv: 0dc13452da863252b385f8e19753f1f4

key: b503aeab5220a50b30208263f207761dcbc6348f2d28b5f76f9c553c707b09a2

验证key正确

加密后的内容: KqwUtAy5JgwDWrRdNvJuVvGfQ9ikXd7LsAEvjGxoILU=

解密后的内容: 这里写需要加密的内容

我工程文件包含unitypackage及cs脚本:https://download.csdn.net/download/qq_33537945/87255889

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值