博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c# 导入PKCS1和PKCS8密钥
阅读量:4163 次
发布时间:2019-05-26

本文共 27198 字,大约阅读时间需要 90 分钟。

之前在一文里,我们已经分析过了PKCS1和PKCS8格式的密钥了

那么,我们现在就做一个c#通用的解析代码,即能解析PKCS1的密钥,也能解析PKCS8的密钥

public static partial class Encryption    {        public static class AsnParser        {            public static RSAParameters ParseRSAPrivateKey(byte[] bt)            {                RSAParameters rsap = new RSAParameters();                // Initial value                List
octets = new List
(); octets.AddRange(bt); int initialCount = bt.Length; // Current value byte[] value = null; // Checkpoint int position = CurrentPosition(initialCount, octets); // Sanity Check int length = 0; byte b = 0; length = NextSequence(ref initialCount, ref octets, out b); if (length != RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect Sequence Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } // Checkpoint position = CurrentPosition(initialCount, octets); // Version value = NextInteger(ref initialCount, ref octets); if (0x00 != value[0]) { StringBuilder sb = new StringBuilder("Incorrect PrivateKeyInfo Version. "); BigInteger v = new BigInteger(value); sb.AppendFormat("Expected: 0, Specified: {0}", v.ToString(10)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } // Checkpoint position = CurrentPosition(initialCount, octets); // Ignore Sequence - AlgorithmIdentifier length = NextSequence(ref initialCount, ref octets, out b); if (0x30 == b) // PKCS8 { if (length > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect AlgorithmIdentifier Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } // Checkpoint position = CurrentPosition(initialCount, octets); // Grab the OID value = NextOID(ref initialCount, ref octets); byte[] oid = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; if (!EqualOid(value, oid)) { //throw new BerDecodeException("Expected OID 1.2.840.113549.1.1.1", position); throw new Exception("Expected OID 1.2.840.113549.1.1.1"); } // Optional Parameters if (IsNextNull(octets)) { NextNull(ref initialCount, ref octets); // Also OK: value = parser.Next(); } else { // Gracefully skip the optional data value = Next(ref initialCount, ref octets); } // Checkpoint position = CurrentPosition(initialCount, octets); // Ignore OctetString - PrivateKey length = NextOctetString(ref initialCount, ref octets); if (length > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect PrivateKey Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } // Checkpoint position = CurrentPosition(initialCount, octets); // Ignore Sequence - RSAPrivateKey length = NextSequence(ref initialCount, ref octets, out b); if (length < RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect RSAPrivateKey Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } // Checkpoint position = CurrentPosition(initialCount, octets); // Version value = NextInteger(ref initialCount, ref octets); if (0x00 != value[0]) { StringBuilder sb = new StringBuilder("Incorrect RSAPrivateKey Version. "); BigInteger v = new BigInteger(value); sb.AppendFormat("Expected: 0, Specified: {0}", v.ToString(10)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } rsap.Modulus = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); rsap.Exponent = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); rsap.D = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); rsap.P = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); rsap.Q = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); rsap.DP = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); rsap.DQ = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); rsap.InverseQ = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); } if (0x02 == b) // PKCS1 { rsap.Modulus = TrimLeadingZero(GetOctets(ref initialCount, ref octets, length)); rsap.Exponent = TrimLeadingZero(GetOctets(ref initialCount, ref octets, NextSequence(ref initialCount, ref octets, out b))); rsap.D = TrimLeadingZero(GetOctets(ref initialCount, ref octets, NextSequence(ref initialCount, ref octets, out b))); rsap.P = TrimLeadingZero(GetOctets(ref initialCount, ref octets, NextSequence(ref initialCount, ref octets, out b))); rsap.Q = TrimLeadingZero(GetOctets(ref initialCount, ref octets, NextSequence(ref initialCount, ref octets, out b))); rsap.DP = TrimLeadingZero(GetOctets(ref initialCount, ref octets, NextSequence(ref initialCount, ref octets, out b))); rsap.DQ = TrimLeadingZero(GetOctets(ref initialCount, ref octets, NextSequence(ref initialCount, ref octets, out b))); rsap.InverseQ = TrimLeadingZero(GetOctets(ref initialCount, ref octets, NextSequence(ref initialCount, ref octets, out b))); } return rsap; } public static RSAParameters ParseRSAPublicKey(byte[] bt) { RSAParameters rsap = new RSAParameters(); // Initial value List
octets = new List
(); octets.AddRange(bt); int initialCount = bt.Length; byte b = 0; // Current value byte[] value = null; // Sanity Check int length = 0; // Checkpoint int position = CurrentPosition(initialCount, octets); // Ignore Sequence - PublicKeyInfo length = NextSequence(ref initialCount, ref octets, out b); if (length != RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect Sequence Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } // Checkpoint position = CurrentPosition(initialCount, octets); // Ignore Sequence - AlgorithmIdentifier length = NextSequence(ref initialCount, ref octets, out b); if (length > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect AlgorithmIdentifier Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } // Checkpoint position = CurrentPosition(initialCount, octets); // Grab the OID value = NextOID(ref initialCount, ref octets); byte[] oid = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; if (!EqualOid(value, oid)) { //throw new BerDecodeException("Expected OID 1.2.840.113549.1.1.1", position); throw new Exception("Expected OID 1.2.840.113549.1.1.1"); } // Optional Parameters if (IsNextNull(octets)) { NextNull(ref initialCount, ref octets); // Also OK: value = parser.Next(); } else { // Gracefully skip the optional data value = Next(ref initialCount, ref octets); } // Checkpoint position = CurrentPosition(initialCount, octets); // Ignore BitString - PublicKey length = NextBitString(ref initialCount, ref octets); if (length > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect PublicKey Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), (RemainingBytes(octets)).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } // Checkpoint position = CurrentPosition(initialCount, octets); // Ignore Sequence - RSAPublicKey length = NextSequence(ref initialCount, ref octets, out b); if (length < RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect RSAPublicKey Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } rsap.Modulus = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); rsap.Exponent = TrimLeadingZero(NextInteger(ref initialCount, ref octets)); return rsap; } public static byte[] ExportRSAPrivateKey(RSAParameters rp, RSA.PaddingType padding) { int count = 0; List
bytes = new List
(); bytes.Add(rp.InverseQ); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 129, 128 }); count += bytes[bytes.Count - 1].Length; bytes.Add(rp.DQ); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 129, 128 }); count += bytes[bytes.Count - 1].Length; bytes.Add(rp.DP); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 129, 128 }); count += bytes[bytes.Count - 1].Length; bytes.Add(rp.Q); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 129, 128 }); count += bytes[bytes.Count - 1].Length; bytes.Add(rp.P); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 129, 128 }); count += bytes[bytes.Count - 1].Length; bytes.Add(rp.D); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 130, 1, 0 }); count += bytes[bytes.Count - 1].Length; bytes.Add(rp.Exponent); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 3 }); count += bytes[bytes.Count - 1].Length; bytes.Add(rp.Modulus); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 130, 1, 0 }); count += bytes[bytes.Count - 1].Length; switch (padding) { case RSA.PaddingType.PKCS1: break; case RSA.PaddingType.PKCS8: bytes.Add(new byte[] { 2, 1, 0 }); count += bytes[bytes.Count - 1].Length; bytes.Add(IntToByte(count)); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 48, 130 }); count += bytes[bytes.Count - 1].Length; bytes.Add(IntToByte(count)); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 4, 130 }); count += bytes[bytes.Count - 1].Length; break; default: throw new Exception("Invalid RSA PaddingType"); } bytes.Add(new byte[] { 2, 1, 0 }); count += bytes[bytes.Count - 1].Length; bytes.Add(IntToByte(count)); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 48, 130 }); count += bytes[bytes.Count - 1].Length; byte[] result = new byte[count]; int cur = 0; for (var i = 0; i < bytes.Count; i++) { Array.Copy(bytes[i], 0, result, count - bytes[i].Length - cur, bytes[i].Length); cur += bytes[i].Length; } return result; } public static byte[] ExportRSAPublicKey(RSAParameters rp) { int count = 0; List
bytes = new List
(); bytes.Add(rp.Exponent); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 3 }); count += bytes[bytes.Count - 1].Length; bytes.Add(rp.Modulus); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 2, 130, 1, 1, 0 }); count += bytes[bytes.Count - 1].Length; bytes.Add(IntToByte(count)); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 48, 130 }); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 0 }); count += bytes[bytes.Count - 1].Length; bytes.Add(IntToByte(count)); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130 }); count += bytes[bytes.Count - 1].Length; bytes.Add(IntToByte(count)); count += bytes[bytes.Count - 1].Length; bytes.Add(new byte[] { 48, 130 }); count += bytes[bytes.Count - 1].Length; byte[] result = new byte[count]; int cur = 0; for (var i = 0; i < bytes.Count; i++) { Array.Copy(bytes[i], 0, result, count - bytes[i].Length - cur, bytes[i].Length); cur += bytes[i].Length; } return result; } private static byte[] IntToByte(int i) { if (i < 256) { return new byte[] { (byte)i }; } string h = i.ToString("x"); MatchCollection mc = RegexExpand.Matches(h, @"[a-f0-9]{1,2}(?=([a-f0-9]{2})*$)", RegexOptions.IgnoreCase); List
result = new List
(); for (int ii = 0; ii < mc.Count; ii++) { result.Add((byte)Convert.ToInt16(mc[ii].Value, 16)); } return result.ToArray(); } private static byte[] TrimLeadingZero(byte[] values) { byte[] r = null; if ((0x00 == values[0]) && (values.Length > 1)) { r = new byte[values.Length - 1]; Array.Copy(values, 1, r, 0, values.Length - 1); } else { r = new byte[values.Length]; Array.Copy(values, r, values.Length); } return r; } private static int NextBitString(ref int initialCount, ref List
octets) { int position = CurrentPosition(initialCount, octets); try { byte b = GetNextOctet(ref initialCount, ref octets); if (0x03 != b) { StringBuilder sb = new StringBuilder("Expected Bit String. "); sb.AppendFormat("Specified Identifier: {0}", b.ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } int length = GetLength(ref initialCount, ref octets); // We need to consume unused bits, which is the first // octet of the remaing values b = octets[0]; octets.RemoveAt(0); length--; if (0x00 != b) { //throw new BerDecodeException("The first octet of BitString must be 0", position); throw new Exception("The first octet of BitString must be 0"); } return length; } catch (ArgumentOutOfRangeException ex) { //throw new BerDecodeException("Error Parsing Key", position, ex); throw ex; } } private static int NextOctetString(ref int initialCount, ref List
octets) { int position = CurrentPosition(initialCount, octets); try { byte b = GetNextOctet(ref initialCount, ref octets); if (0x04 != b) { StringBuilder sb = new StringBuilder("Expected Octet String. "); sb.AppendFormat("Specified Identifier: {0}", b.ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } int length = GetLength(ref initialCount, ref octets); if (length > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect Octet String Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } return length; } catch (ArgumentOutOfRangeException ex) { //throw new BerDecodeException("Error Parsing Key", position, ex); throw ex; } } private static byte[] Next(ref int initialCount, ref List
octets) { int position = CurrentPosition(initialCount, octets); try { byte b = GetNextOctet(ref initialCount, ref octets); int length = GetLength(ref initialCount, ref octets); if (length > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } return GetOctets(ref initialCount, ref octets, length); } catch (ArgumentOutOfRangeException ex) { //throw new BerDecodeException("Error Parsing Key", position, ex); throw ex; } } private static int NextNull(ref int initialCount, ref List
octets) { int position = CurrentPosition(initialCount, octets); try { byte b = GetNextOctet(ref initialCount, ref octets); if (0x05 != b) { StringBuilder sb = new StringBuilder("Expected Null. "); sb.AppendFormat("Specified Identifier: {0}", b.ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } // Next octet must be 0 b = GetNextOctet(ref initialCount, ref octets); if (0x00 != b) { StringBuilder sb = new StringBuilder("Null has non-zero size. "); sb.AppendFormat("Size: {0}", b.ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } return 0; } catch (ArgumentOutOfRangeException ex) { //throw new BerDecodeException("Error Parsing Key", position, ex); throw ex; } } private static bool IsNextNull(List
octets) { return 0x05 == octets[0]; } private static bool EqualOid(byte[] first, byte[] second) { if (first.Length != second.Length) { return false; } for (int i = 0; i < first.Length; i++) { if (first[i] != second[i]) { return false; } } return true; } private static byte[] NextOID(ref int initialCount, ref List
octets) { int position = CurrentPosition(initialCount, octets); try { byte b = GetNextOctet(ref initialCount, ref octets); if (0x06 != b) { StringBuilder sb = new StringBuilder("Expected Object Identifier. "); sb.AppendFormat("Specified Identifier: {0}", b.ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } int length = GetLength(ref initialCount, ref octets); if (length > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect Object Identifier Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } byte[] values = new byte[length]; for (int i = 0; i < length; i++) { values[i] = octets[0]; octets.RemoveAt(0); } return values; } catch (ArgumentOutOfRangeException ex) { //throw new BerDecodeException("Error Parsing Key", position, ex); throw ex; } } private static byte[] NextInteger(ref int initialCount, ref List
octets) { int position = CurrentPosition(initialCount, octets); try { byte b = GetNextOctet(ref initialCount, ref octets); if (0x02 != b) { StringBuilder sb = new StringBuilder("Expected Integer. "); sb.AppendFormat("Specified Identifier: {0}", b.ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } int length = GetLength(ref initialCount, ref octets); if (length > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect Integer Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } return GetOctets(ref initialCount, ref octets, length); } catch (ArgumentOutOfRangeException ex) { //throw new BerDecodeException("Error Parsing Key", position, ex); throw ex; } } private static int CurrentPosition(int initialCount, List
octets) { return initialCount - octets.Count; } private static int RemainingBytes(List
octets) { return octets.Count; } private static byte[] GetOctets(ref int initialCount, ref List
octets, int octetCount) { int position = CurrentPosition(initialCount, octets); if (octetCount > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", octetCount.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } byte[] values = new byte[octetCount]; try { octets.CopyTo(0, values, 0, octetCount); octets.RemoveRange(0, octetCount); } catch (ArgumentOutOfRangeException ex) { //throw new BerDecodeException("Error Parsing Key", position, ex); throw ex; } return values; } private static byte GetNextOctet(ref int initialCount, ref List
octets) { int position = CurrentPosition(initialCount, octets); if (0 == RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", 1.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } byte b = GetOctets(ref initialCount, ref octets, 1)[0]; return b; } private static int GetLength(ref int initialCount, ref List
octets) { int length = 0; // Checkpoint int position = CurrentPosition(initialCount, octets); try { byte b = GetNextOctet(ref initialCount, ref octets); if (b == (b & 0x7f)) { return b; } int i = b & 0x7f; if (i > 4) { StringBuilder sb = new StringBuilder("Invalid Length Encoding. "); sb.AppendFormat("Length uses {0} octets", i.ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } while (0 != i--) { // shift left length <<= 8; length |= GetNextOctet(ref initialCount, ref octets); } } catch (ArgumentOutOfRangeException ex) { //throw new BerDecodeException("Error Parsing Key", position, ex); throw ex; } return length; } private static int NextSequence(ref int initialCount, ref List
octets, out byte b) { int position = CurrentPosition(initialCount, octets); try { b = GetNextOctet(ref initialCount, ref octets); int length = 0; if (0x30 == b) // PKCS8 { length = GetLength(ref initialCount, ref octets); if (length > RemainingBytes(octets)) { StringBuilder sb = new StringBuilder("Incorrect Sequence Size. "); sb.AppendFormat("Specified: {0}, Remaining: {1}", length.ToString(CultureInfo.InvariantCulture), RemainingBytes(octets).ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } } if (0x02 == b) // PKCS1 { byte x = GetOctets(ref initialCount, ref octets, 1)[0]; if (x == 0x81) { length = GetOctets(ref initialCount, ref octets, 1)[0]; } else if (x == 0x82) { byte h = GetOctets(ref initialCount, ref octets, 1)[0]; byte l = GetOctets(ref initialCount, ref octets, 1)[0]; byte[] m = { l, h, 0x00, 0x00 }; length = BitConverter.ToInt32(m, 0); //length = h<<8|l; } else { length = x; } while (octets[0] == 0x00) { GetOctets(ref initialCount, ref octets, 1); length--; } } if (length == 0) { StringBuilder sb = new StringBuilder("Expected Sequence. "); sb.AppendFormat("Specified Identifier: {0}", b.ToString(CultureInfo.InvariantCulture)); //throw new BerDecodeException(sb.ToString(), position); throw new Exception(sb.ToString()); } return length; } catch (ArgumentOutOfRangeException ex) { //throw new BerDecodeException("Error Parsing Key", position, ex); throw ex; } } } }

调用方法也很简单

string base64 = FileHelper.FileToString(fi.FullName);if (Regex.IsMatch(base64, @"^[-]+BEGIN")){    base64 = Regex.Match(base64, @"(?<=KEY[-]+[\r\n]+)[\s\S]+(?=[\r\n]+[-]+END)").Value;    base64 = Regex.Replace(base64, @"[\r\n]+", "");}RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(8);rsa.ImportParameters(AsnParser.ParseRSAPrivateKey(Convert.FromBase64String(base64)));

直接从密钥文件中得到的密钥数据,掐头去尾,把回车换行去掉之后转个码,然后用AsnParser解析成RSAParameters对象,直接导入

至于PKCS1和PKCS8的区别,则在AsnParser的NextSequence方法中有体现,第八个字节为48,即0x30时,为PKCS8格式,如果第八个字节为2,即0x02时,则为PKCS1,为其他值时,则为验证数据

转载地址:http://kavxi.baihongyu.com/

你可能感兴趣的文章
别因为要学的太多反而压垮自己
查看>>
给自己写一封信!隔段时间看一遍
查看>>
程序员提高英语阅读水平
查看>>
Java程序员应该掌握哪些技术
查看>>
从程序员到架构师的方法与逻辑
查看>>
23个设计模式的简明教程
查看>>
Redis错误配置详解
查看>>
WinHex中文版下载 v16.9 汉化破解版
查看>>
Javascript中最常用的125个经典技巧
查看>>
Java面试题和答案解析
查看>>
程序员既要写好代码,又要写好文档
查看>>
20个设计模式和软件设计面试问题
查看>>
微管理—给你一个技术团队,你该怎么管
查看>>
流程在企业内的作用及成熟度
查看>>
项目设计到开发过程中,需要注意的知识点总结
查看>>
程序员生存定律-六个程序员的故事(1)
查看>>
[企管怪谈]企业怎么留住领导?
查看>>
STL容器与默认拷贝构造函数,默认赋值函数
查看>>
为什么C/C++语言使用指针
查看>>
程序员的自我修养(1)——操作系统篇
查看>>