- 浏览: 208805 次
- 性别:
- 来自: 江西
文章分类
- 全部博客 (109)
- C# (29)
- ASP.NET (30)
- MSSQL (29)
- javascript (9)
- cmd (3)
- ORACLE (4)
- log4j (1)
- window (5)
- FTP (1)
- Shell (1)
- java (1)
- IIS (7)
- html (11)
- SQL (3)
- Jquery (11)
- IE (3)
- 火狐、谷歌 (2)
- wince (2)
- JSON (5)
- List (1)
- Foreach (1)
- SQLhelper (1)
- Ajax (1)
- Firebird (1)
- mysql (7)
- js (2)
- jQuery.autocomplete (1)
- dataTable (1)
- Http (1)
- get (1)
- datetime (1)
- powshell (1)
- URL Protocol (1)
- Office (1)
- Excel (1)
- ASP.NET,算法,秘钥 (1)
- 浏览器 (1)
- Tomcat (1)
最新评论
使用PBKDF2算法方案,该算法是一个标准的密钥导出算法,可用于导出对称密钥, 应用PBKDF2的密钥导出函数主要是用来导出根秘钥(也叫初始密钥),然后用此根秘钥加密工作秘钥(工作秘钥由信息中心通过https传送给iRAD客户端或者其他安全通道预共享的方式传送给iRad客户端,用于记住密码功能中的加密)保存到本地。在使用PBKDF2导出根秘钥时,用到两个参数“初始向量”和“秘钥因子”, 为了满足合规要求,一是要求这两个参数都要随机生成(长度不少于128位或16字节);二是要求这两个参数分开存储,通常的做法时将初始向量数组(通过预设的随机运算——例如来自于openssl的安全随机数序列,然后产生初始向量数组)硬编码到代码中,而将秘钥因子(16进制)存储到配置文件中。
具体到利用PBKDF2算法(PKCS#5)来导出初始密钥的使用,这里提供一个参考:
计算公式为:DK = PBKDF2(Password, Salt, count, dkLen)
输入:
Password :用户输入的口令或者读取的一串字符串,这里使用“密钥因子”。
Salt :盐值,字符串,这里使用“初始向量”
count :迭代次数,正整数,默认使用“50,000”次,华为要求不小于10000次
dkLen :导出密钥的字节长度,正整数,该长度需根据应用程序或密码应用模块所需要的工作密钥长度来定义,以AES128加密算法为例,密钥长度为128bit,即16字节。
输出:
DK :导出的密钥,长度为dkLen个字节的字符串。
Hash函数:
优先使用HmacSHA256、HmacSHA384、HmacSHA512等强密码算法,如果是由于使用的加密库等方面的原因导致不支持相应的强密码算法,也可以使用HmacSHA1,但迭代次数(count)需定义为“100,000”次。
具体到利用PBKDF2算法(PKCS#5)来导出初始密钥的使用,这里提供一个参考:
计算公式为:DK = PBKDF2(Password, Salt, count, dkLen)
输入:
Password :用户输入的口令或者读取的一串字符串,这里使用“密钥因子”。
Salt :盐值,字符串,这里使用“初始向量”
count :迭代次数,正整数,默认使用“50,000”次,华为要求不小于10000次
dkLen :导出密钥的字节长度,正整数,该长度需根据应用程序或密码应用模块所需要的工作密钥长度来定义,以AES128加密算法为例,密钥长度为128bit,即16字节。
输出:
DK :导出的密钥,长度为dkLen个字节的字符串。
Hash函数:
优先使用HmacSHA256、HmacSHA384、HmacSHA512等强密码算法,如果是由于使用的加密库等方面的原因导致不支持相应的强密码算法,也可以使用HmacSHA1,但迭代次数(count)需定义为“100,000”次。
using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace TestPassword { public class PasswordSecurity { class InvalidHashException : Exception { public InvalidHashException() { } public InvalidHashException(string message) : base(message) { } public InvalidHashException(string message, Exception inner) : base(message, inner) { } } class CannotPerformOperationException : Exception { public CannotPerformOperationException() { } public CannotPerformOperationException(string message) : base(message) { } public CannotPerformOperationException(string message, Exception inner) : base(message, inner) { } } public class PasswordStorage { // These constants may be changed without breaking existing hashes. public const int SALT_BYTES = 16; // The number of bytes of salt. By default, 24 bytes, which is 192 bits. This is more than enough. This constant should not be changed. public const int HASH_BYTES = 16; public const int PBKDF2_ITERATIONS = 100000; // PBKDF2 迭代次数,默认32000 // These constants define the encoding and may not be changed. // 对应format: algorithm:iterations:hashSize:salt:hash public const int HASH_ALGORITHM_INDEX = 0; // 加密方式所对应的索引,目前只支持sha1 public const int ITERATION_INDEX = 1; // 迭代次数所对应的索引 public const int HASH_SIZE_INDEX = 2; // hashsize所对应的索引 public const int SALT_INDEX = 3; // salt值所对应的索引 public const int PBKDF2_INDEX = 4; // hash值所对应的索引 public const int HASH_SECTIONS = 5; // 总共存储几段数据;根据分隔符,对应 format中字段 private const string HASH_ALGORITHM = "sha1"; // 加密方式,目前只支持sha1 /// <summary> /// 创建hash+salt后的密码 /// </summary> /// <param name="password">原始密码,比如abcdef</param> /// <returns></returns> public static string CreateHash(string password) { // Generate a random salt byte[] salt = new byte[SALT_BYTES]; try { using (RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider()) { csprng.GetBytes(salt); } } catch (CryptographicException ex) { throw new CannotPerformOperationException("Random number generator not available.", ex); } catch (ArgumentNullException ex) { throw new CannotPerformOperationException("Invalid argument given to random number generator.", ex); } byte[] hash = PBKDF2(password, salt, PBKDF2_ITERATIONS, HASH_BYTES); // format: algorithm:iterations:hashSize:salt:hash /* * algorithm is the name of the cryptographic hash function ("sha1"). iterations is the number of PBKDF2 iterations ("64000"). hashSize is the length, in bytes, of the hash field (after decoding). salt is the salt, base64 encoded. hash is the PBKDF2 output, base64 encoded. It must encode hashSize bytes. * */ return Convert.ToBase64String(hash); //return string.Format("{0}:{1}:{2}:{3}:{4}" // , HASH_ALGORITHM // , PBKDF2_ITERATIONS // , hash.Length // , Convert.ToBase64String(salt) // , Convert.ToBase64String(hash)); } /// <summary> /// 验证密码是否有效 /// </summary> /// <param name="password">原始密码,比如abcdef</param> /// <param name="goodHash">已存的hash,从DB中读取;format: algorithm:iterations:hashSize:salt:hash</param> /// <returns></returns> public static bool VerifyPassword(string password, string goodHash) { char[] delimiter = { ':' }; string[] split = goodHash.Split(delimiter); if (split.Length != HASH_SECTIONS) { throw new InvalidHashException("Fields are missing from the password hash."); } // We only support SHA1 with C#. if (split[HASH_ALGORITHM_INDEX] != HASH_ALGORITHM) { throw new CannotPerformOperationException("Unsupported hash type."); } int iterations = 0; try { iterations = Int32.Parse(split[ITERATION_INDEX]); } catch (ArgumentNullException ex) { throw new CannotPerformOperationException("Invalid argument given to Int32.Parse", ex); } catch (FormatException ex) { throw new InvalidHashException("Could not parse the iteration count as an integer.", ex); } catch (OverflowException ex) { throw new InvalidHashException("The iteration count is too large to be represented.", ex); } if (iterations < 1) { throw new InvalidHashException("Invalid number of iterations. Must be >= 1."); } byte[] salt = null; try { salt = Convert.FromBase64String(split[SALT_INDEX]); } catch (ArgumentNullException ex) { throw new CannotPerformOperationException("Invalid argument given to Convert.FromBase64String", ex); } catch (FormatException ex) { throw new InvalidHashException("Base64 decoding of salt failed.", ex); } byte[] hash = null; try { hash = Convert.FromBase64String(split[PBKDF2_INDEX]); } catch (ArgumentNullException ex) { throw new CannotPerformOperationException("Invalid argument given to Convert.FromBase64String", ex); } catch (FormatException ex) { throw new InvalidHashException("Base64 decoding of pbkdf2 output failed.", ex); } int storedHashSize = 0; try { storedHashSize = Int32.Parse(split[HASH_SIZE_INDEX]); } catch (ArgumentNullException ex) { throw new CannotPerformOperationException("Invalid argument given to Int32.Parse", ex); } catch (FormatException ex) { throw new InvalidHashException("Could not parse the hash size as an integer.", ex); } catch (OverflowException ex) { throw new InvalidHashException("The hash size is too large to be represented.", ex); } if (storedHashSize != hash.Length) { throw new InvalidHashException("Hash length doesn't match stored hash length."); } byte[] testHash = PBKDF2(password, salt, iterations, hash.Length); return SlowEquals(hash, testHash); } private static bool SlowEquals(byte[] a, byte[] b) { uint diff = (uint)a.Length ^ (uint)b.Length; for (int i = 0; i < a.Length && i < b.Length; i++) { diff |= (uint)(a[i] ^ b[i]); } return diff == 0; } private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes) { using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt)) { pbkdf2.IterationCount = iterations; return pbkdf2.GetBytes(outputBytes); } } /// <summary> /// HMAC-SHA256 加密 /// </summary> /// <param name="input"> 要加密的字符串 </param> /// <param name="key"> 密钥 </param> /// <param name="encoding"> 字符编码 </param> /// <returns></returns> public static string HMACSHA256Encrypt(string input, string key, Encoding encoding) { return HashEncrypt(new HMACSHA256(encoding.GetBytes(key)), input, encoding); } /// <summary> /// 哈希加密算法 /// </summary> /// <param name="hashAlgorithm"> 所有加密哈希算法实现均必须从中派生的基类 </param> /// <param name="input"> 待加密的字符串 </param> /// <param name="encoding"> 字符编码 </param> /// <returns></returns> private static string HashEncrypt(HashAlgorithm hashAlgorithm, string input, Encoding encoding) { var data = hashAlgorithm.ComputeHash(encoding.GetBytes(input)); return BitConverter.ToString(data).Replace("-", ""); } } } } ///生成根秘钥 using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace TestPassword { class Program { public Program() { } /// <summary> /// 加密字符串 /// </summary> /// <param name="rmd"></param> /// <param name="str"></param> /// <returns></returns> public string CharEncrypt(RootModel rmd, string str) { string strKey = string.Empty; //解密工作秘钥 (加密方式AES/CBC/ISO10126) string strWorkKey = AesHelper.AESDecryptNew(rmd.workKeyEcpt, rmd.rootKey, rmd.workKeyIV); //先UTF-8,BASE 64 string EnStr = Convert.ToBase64String(Encoding.UTF8.GetBytes(str)); //加密字符串 strKey = AesHelper.AESEncrypt(EnStr, strWorkKey, RNGCSP.RNGGetRandom()); if(!string.IsNullOrWhiteSpace(strKey)) { strKey += "@" + RNGCSP.RNGGetRandom(); } return strKey; } /// <summary> /// 解密字符串 /// </summary> /// <param name="rmd"></param> /// <returns></returns> public string WorkDecrypt(RootModel rmd, string strDecrypt) { //解密工作秘钥 (加密方式AES/CBC/ISO10126) string strWorkKey= AesHelper.AESDecryptNew(rmd.workKeyEcpt, rmd.rootKey, rmd.workKeyIV); string strNew = string.Empty; if (!string.IsNullOrWhiteSpace(strDecrypt)) { if(strDecrypt.Contains("@")) { string[] arr = strDecrypt.Split('@'); if (arr.Length>1) { //解密字符串 strNew = AesHelper.AESDecryptNew(arr[0], strWorkKey, arr[1]); } } } return Encoding.UTF8.GetString(Convert.FromBase64String(strNew)); } static void Main(string[] args) { Program pro = new Program(); RootModel rm = new RootModel(); //根密钥 rm.rootKey = "M2UyYzQ0NmMwNjNjYTQ4OA=="; //工作秘钥IV rm.workKeyIV = "mlJDbTEmDjBD/1xy6jBomg=="; //工作秘钥加密后 rm.workKeyEcpt = "3R8RaUxY1Fy7UJ8BvOdYbYxkL6fzdXaOfObdl21bxaI="; //解密字符串 string strDecrypt = "EjwONCy04h0/AE3l+A4y9A==@Uz2VFravYLeG+oyqrFUS7w=="; //解密字符串 //string strChar = pro.WorkDecrypt(rm, strDecrypt); //加密字符串 string strEnChar = pro.CharEncrypt(rm, "testpjf"); Console.WriteLine(strEnChar); //string strChar = pro.WorkDecrypt(rm, strEnChar); ////生成根秘钥 初始向量、秘钥因子(字符串) byte[] RootKey = new byte[32]; ////生成根密钥(PBDF2导出根密钥) string RootSecretKey = pro.EncodePassWord("M2UyYzQ0NmMwNjNjYTQ4OA=="); Console.ReadKey(); } public string EncodePassWord(string strPwd) { return PasswordSecurity.PasswordStorage.CreateHash(strPwd); // sha1:64000:18:ou2x9eUw82+dnxGetsTaNJLzLXiaElu8:7Ga+qwM4g8Bb/iPOfnQTd6HA // sha1:64000:18:8daBj8djNvUBLE5Y3vRTvMaooydwBfYg:EV9mmvk1oinBGPoufd3aQ85m //Assert.IsNotNull(hashPassword); } public bool decodePassWord(string strPwd,string strEncodePwd) { return PasswordSecurity.PasswordStorage.VerifyPassword(strPwd,strEncodePwd); // Assert.IsTrue(result); } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TestPassword { using System; using System.IO; using System.Text; using System.Security.Cryptography; //生成随机数 public class RNGCSP { private static RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); private static int S_BYTES = 16; public static string RNGGetRandom() { string strResult=string.Empty; byte[] salt = new byte[S_BYTES]; try { using (RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider()) { csprng.GetBytes(salt); } } catch (CryptographicException ex) { return null; } return Convert.ToBase64String(salt); } } } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TestPassword { public class RootModel { /// <summary> /// 加密后根密钥 /// </summary> public string rootKey { get; set; } /// <summary> /// 加密后工作秘钥 /// </summary> public string workKeyEcpt { get; set; } /// <summary> /// 工作IV盐值 /// </summary> public string workKeyIV { get; set; } } } using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace TestPassword { public class AesHelper { /// <summary> /// AES加密 (128-ECB加密模式) /// </summary> /// <param name="toEncrypt">内容</param> /// <param name="key">秘钥</param> /// <returns></returns> public static string AESEncrypt(string toEncrypt, string key,string IV) { try { // byte[] keyArray = Convert.FromBase64String(key); byte[] toEncryptArray = Convert.FromBase64String(Convert.ToBase64String(Encoding.UTF8.GetBytes(toEncrypt))); byte[] IVArray = Convert.FromBase64String(IV); using (RijndaelManaged rDel = new RijndaelManaged()) { rDel.Key = keyArray; rDel.IV = IVArray; rDel.Mode = CipherMode.CBC; rDel.Padding = PaddingMode.ISO10126; ICryptoTransform cTransform = rDel.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } } catch { return null; } } /// <summary> /// AES解密(128-ECB加密模式) /// </summary> /// <param name="toDecrypt">密文</param> /// <param name="key">秘钥(Base64String)</param> /// <returns></returns> public static string AESDecryptNew(string toDecrypt, string Rootkey,string IV) { try { byte[] RootkeyArray = Convert.FromBase64String(Rootkey); //128bit byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); byte[] IVArray = Convert.FromBase64String(IV); //128bit using ( RijndaelManaged rDel = new RijndaelManaged()) { rDel.Key = RootkeyArray; //获取或设置对称算法的密钥 rDel.Mode = CipherMode.CBC; //获取或设置对称算法的运算模式,必须设置为CBC rDel.IV = IVArray; rDel.Padding = PaddingMode.ISO10126; //获取或设置对称算法中使用的填充模式,必须设置为PKCS7 ICryptoTransform cTransform = rDel.CreateDecryptor(); //用当前的 Key 属性和初始化向量 (IV) 创建对称解密器对象 byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray); } } catch { return null; } } } }
发表评论
-
AES 动态生成秘钥
2018-09-28 14:29 11661:方法一 通过账号+日期进行AES128位加密,取其前面16 ... -
Microsoft Office Excel 不能访问文件“EXCEL.xls”
2018-08-25 16:31 1061Microsoft Office Excel 不能访问文件“X ... -
微信分享
2017-04-20 14:15 602/// <summary> // ... -
web.config 为某个单独页面设置编码格式
2017-03-31 18:28 1066原文链接:http://www.cnblogs.com/m ... -
json日期格式转换成日期字符串
2016-08-29 10:31 2090这里进行去掉json日期的\date\字符串: st ... -
C# http get请求 判断是否存在该图片信息
2016-08-29 10:25 900/// <summary> /// h ... -
C# 将json转换成Datatable
2016-08-29 10:19 1235/// <summary> /// 将 ... -
jQuery.autocomplete.js乱码问题
2016-07-12 14:01 6621、首先修改jQuery.autocomplete.js 文件 ... -
C# 缓存
2016-06-24 15:27 714using System; using System.Col ... -
jquery table 操作
2014-12-06 19:21 942jQuery在客户端操作Table ... -
Firebird单击嵌入式非安装版使用
2014-03-12 18:48 2396Firebird单击嵌入式非安 ... -
C#开发常用的工具类
2014-02-26 13:47 1275using System; using System.Col ... -
SQLhelper帮助类
2014-02-26 13:33 4626using System; using System.Col ... -
C#中将JSon数据转换成实体类,将实体类转换成Json
2014-02-26 13:22 43882using System; using System.Col ... -
C#反射机制介绍
2014-02-25 11:26 1723反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编 ... -
LIST集合已修改;可能无法执行枚举操作。
2014-02-18 23:17 984foreach是取只读的,在取的时候数据不 能变(包括修改,删 ... -
COM 类工厂中 CLSID 为 {A86BB4D8-209D-40E1-87A6-7AA236094FAD} 的组件时失败,原因是出现以下错误: 800401
2013-09-12 13:21 1564第一: 检查dll文件是否存在 第二: 兼容问题,看i ... -
ASP.NET中url传递中文的解决方案,传递参数为汉字时出现乱码等问题
2013-09-11 16:13 872来源:http://hi.baidu.com/netkey/i ... -
常用的WebService一览表
2013-09-05 10:43 655转载:http://blog.csdn.net/wangzh3 ... -
批量插入数据 C# SqlBulkCopy使用
2013-09-05 10:31 907private static void Dat ...
相关推荐
C#加密算法汇总 C#加密算法 C#加密算法 C#加密算法
C#可逆加密算法收集
C#, AES 加密算法, 含示例 . . .
C#国密加密算法SM2,SM3,SM4的一个实现案例,不涉及具体的算法剖析,在网络上关于这个加密算法的文档较少,切在跨语言加密解密上会存在一些问题,所以整理。
c# 可逆 加密 解密算法
c#常用加密算法 pdf 对C# 中常用加解密算法进行了实现 直接可以用
C# 常用加密算法 包括MD5 base64 hax等
c#对称加密算法源码,自己写的,希望对大家有用
C#加密算法汇总,可逆加密解密,SHA1加密字符串
关于C#加密算法的实现,包括RSA、MD5,对称加密,公钥私钥对
在提供接口时,常常需要对请求的报文加密,解密。最常用简单快捷有效的方法,就是对称加密、解密。下面提供项目中使用的加解密方法,可直接用于生产。
我这里是在VS下创建的项目 直接复制进去就可以运行 里面还处理了无法保存到本地的方法
C#实现DES加密算法。 VS2008 希望对大家有帮助
C# 基于Rijndael加密算法对XML文档加密和解密
C# Desc加密算法 using System; using System.Collections.Generic; using System.Text; using System.Security.Cryptography; using System.IO;
c# 对称加密算法 例子~~~~~~~~~~~~~~ http://www.dotnetdev.cn
一个C#实现的DES加密算法类,里面有dll可以直接加在进你的工程文件。
C# 对称加密类算法 C# 对称加密类算法 C# 对称加密类算法
c#加密算法
整理了诸如:对称加密算法,不对称加密算法,哈希加密算法,MD5加密算法,RSA算法 ,DES算法,ElGamal算法等加密算法并附带程序代码