C# RSA加密解密
Posted you000bbs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# RSA加密解密相关的知识,希望对你有一定的参考价值。
1.解析密钥
/// <summary> /// 把二进制密钥解析成RSACryptoServiceProvider /// </summary> /// <param name="privkey"></param> /// <returns></returns> private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey) { byte[] MODULUS, E, D, P, Q, DP, DQ, IQ; // --------- Set up stream to decode the asn.1 encoded RSA private key ------ MemoryStream mem = new MemoryStream(privkey); BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading byte bt = 0; ushort twobytes = 0; int elems = 0; try { twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81) binr.ReadByte(); //advance 1 byte else if (twobytes == 0x8230) binr.ReadInt16(); //advance 2 bytes else return null; twobytes = binr.ReadUInt16(); if (twobytes != 0x0102) //version number return null; bt = binr.ReadByte(); if (bt != 0x00) return null; //------ all private key components are Integer sequences ---- elems = GetIntegerSize(binr); MODULUS = binr.ReadBytes(elems); elems = GetIntegerSize(binr); E = binr.ReadBytes(elems); elems = GetIntegerSize(binr); D = binr.ReadBytes(elems); elems = GetIntegerSize(binr); P = binr.ReadBytes(elems); elems = GetIntegerSize(binr); Q = binr.ReadBytes(elems); elems = GetIntegerSize(binr); DP = binr.ReadBytes(elems); elems = GetIntegerSize(binr); DQ = binr.ReadBytes(elems); elems = GetIntegerSize(binr); IQ = binr.ReadBytes(elems); // ------- create RSACryptoServiceProvider instance and initialize with public key ----- CspParameters CspParameters = new CspParameters(); CspParameters.Flags = CspProviderFlags.UseMachineKeyStore; RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters); RSAParameters RSAparams = new RSAParameters(); RSAparams.Modulus = MODULUS; RSAparams.Exponent = E; RSAparams.D = D; RSAparams.P = P; RSAparams.Q = Q; RSAparams.DP = DP; RSAparams.DQ = DQ; RSAparams.InverseQ = IQ; RSA.ImportParameters(RSAparams); return RSA; } catch (Exception ex) { return null; } finally { binr.Close(); } } /// <summary> /// 二进制解析辅助函数 /// </summary> /// <param name="binr"></param> /// <returns></returns> private static int GetIntegerSize(BinaryReader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) //expect integer return 0; bt = binr.ReadByte(); if (bt == 0x81) count = binr.ReadByte(); // data size in next byte else if (bt == 0x82) { highbyte = binr.ReadByte(); // data size in next 2 bytes lowbyte = binr.ReadByte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = BitConverter.ToInt32(modint, 0); } else { count = bt; // we already have the data size } while (binr.ReadByte() == 0x00) { //remove high order zeros in data count -= 1; } binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn‘t a removed zero, so back up a byte return count; }
2.导出私钥字符串格式
/// <summary> /// 导出RSACryptoServiceProvider对象私钥成XML格式 /// </summary> /// <param name="privatekey"></param> /// <returns></returns> public static string GetRSAKeyValueXml(string privatekey) { byte[] data = Convert.FromBase64String(privatekey); RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(data); return rsa.ToXmlString(true); }
3.不可解密的方式加密
/// <summary> /// 加密 /// </summary> /// <param name="txt">待加密字符串</param> /// <param name="privatekey">私钥</param> /// <returns>Base64加案后结果</returns> public static string SHA1(string txt, string rsaXML) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(rsaXML); byte[] data = System.Text.Encoding.UTF8.GetBytes(txt); // return Convert.ToBase64String(rsa.SignData(data, "SHA1")); }
4.普通的加密方式
/// <summary> /// 加密 /// </summary> /// <param name="txt">待加密字符串</param> /// <param name="privatekey">私钥</param> /// <returns>Base64加案后结果</returns> public static string Encrypt(string txt, string rsaXML) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(rsaXML); byte[] data = System.Text.Encoding.UTF8.GetBytes(txt); int MaxBlockSize = rsa.KeySize / 8 - 11; //加密块最大长度限制 if (data.Length <= MaxBlockSize) return Convert.ToBase64String(rsa.Encrypt(data, false)); using (MemoryStream PlaiStream = new MemoryStream(data)) { using (MemoryStream CrypStream = new MemoryStream()) { Byte[] Buffer = new Byte[MaxBlockSize]; int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize); while (BlockSize > 0) { Byte[] ToEncrypt = new Byte[BlockSize]; Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize); Byte[] Cryptograph = rsa.Encrypt(ToEncrypt, false); CrypStream.Write(Cryptograph, 0, Cryptograph.Length); BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize); } return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None); } } }
5.普通的解密方式
/// <summary> /// 解密 /// </summary> public static string Decrypt(string txt, string rsaXML) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(rsaXML); byte[] data = Convert.FromBase64String(txt); int MaxBlockSize = rsa.KeySize / 8; //加密块最大长度限制 if (data.Length <= MaxBlockSize) return System.Text.Encoding.UTF8.GetString(rsa.Decrypt(data, false)); using (MemoryStream PlaiStream = new MemoryStream(data)) { using (MemoryStream CrypStream = new MemoryStream()) { Byte[] Buffer = new Byte[MaxBlockSize]; int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize); while (BlockSize > 0) { Byte[] ToEncrypt = new Byte[BlockSize]; Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize); Byte[] Cryptograph = rsa.Decrypt(ToEncrypt, false); CrypStream.Write(Cryptograph, 0, Cryptograph.Length); BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize); } return System.Text.Encoding.UTF8.GetString(CrypStream.ToArray()); } } }
以上是关于C# RSA加密解密的主要内容,如果未能解决你的问题,请参考以下文章