Пример #1
0
        /// <summary>
        /// 通过公钥或私钥创建RSA,出错抛异常
        /// </summary>
        public RSA(string key)
        {
            if (!key.StartsWith("<"))
            {
                RSAObject = RsaPem.FromPEM(key).GetRSA();
            }
            else
            {
                var rsaParams = new CspParameters
                {
                    Flags = CspProviderFlags.UseMachineKeyStore
                };
                RSAObject = new RSACryptoServiceProvider(rsaParams);

                RSAObject.FromXmlString(key);
            }
        }
Пример #2
0
 /// <summary>
 /// 通过一个pem对象创建RSA,pem为公钥或私钥,出错抛异常
 /// </summary>
 public RSA(RsaPem pem)
 {
     RSAObject = pem.GetRSA();
 }
Пример #3
0
        /// <summary>
        /// 将XML格式密钥转成PEM,支持公钥xml、私钥xml
        /// 出错将会抛出异常
        /// </summary>
        public static RsaPem FromXML(string xml)
        {
            var rtv  = new RsaPem();
            var xmlM = XmlExp.Match(xml);

            if (!xmlM.Success)
            {
                throw new Exception("XML内容不符合要求");
            }

            var tagM = XmlTagExp.Match(xmlM.Groups[1].Value);

            while (tagM.Success)
            {
                string tag = tagM.Groups[1].Value;
                string b64 = tagM.Groups[2].Value;
                byte[] val = Convert.FromBase64String(b64);
                switch (tag)
                {
                case "Modulus":
                    rtv.KeyModulus = val;
                    break;

                case "Exponent":
                    rtv.KeyExponent = val;
                    break;

                case "D":
                    rtv.KeyD = val;
                    break;

                case "P":
                    rtv.ValP = val;
                    break;

                case "Q":
                    rtv.ValQ = val;
                    break;

                case "DP":
                    rtv.ValDp = val;
                    break;

                case "DQ":
                    rtv.ValDq = val;
                    break;

                case "InverseQ":
                    rtv.ValInverseQ = val;
                    break;
                }

                tagM = tagM.NextMatch();
            }

            if (rtv.KeyModulus == null || rtv.KeyExponent == null)
            {
                throw new Exception("XML公钥丢失");
            }

            if (rtv.KeyD != null)
            {
                if (rtv.ValP == null || rtv.ValQ == null || rtv.ValDp == null || rtv.ValDq == null || rtv.ValInverseQ == null)
                {
                    return(new RsaPem(rtv.KeyModulus, rtv.KeyExponent, rtv.KeyD));
                }
            }

            return(rtv);
        }
Пример #4
0
        /// <summary>
        /// 用PEM格式密钥对创建RSA,支持PKCS#1、PKCS#8格式的PEM
        /// 出错将会抛出异常
        /// </summary>
        public static RsaPem FromPEM(string pem)
        {
            RsaPem param = new RsaPem();

            var base64 = PemCode.Replace(pem, "");

            byte[] data = null;
            try
            {
                data = Convert.FromBase64String(base64);
            }
            catch
            {
            }

            if (data == null)
            {
                throw new Exception("PEM内容无效");
            }

            var idx = 0;

            //读取长度
            Func <byte, int> readLen = (first) =>
            {
                if (data[idx] == first)
                {
                    idx++;
                    if (data[idx] == 0x81)
                    {
                        idx++;
                        return(data[idx++]);
                    }

                    if (data[idx] == 0x82)
                    {
                        idx++;
                        return(((data[idx++]) << 8) + data[idx++]);
                    }

                    if (data[idx] < 0x80)
                    {
                        return(data[idx++]);
                    }
                }

                throw new Exception("PEM未能提取到数据");
            };
            //读取块数据
            Func <byte[]> readBlock = () =>
            {
                var len = readLen(0x02);
                if (data[idx] == 0x00)
                {
                    idx++;
                    len--;
                }

                var val = new byte[len];
                for (var i = 0; i < len; i++)
                {
                    val[i] = data[idx + i];
                }

                idx += len;
                return(val);
            };
            //比较data从idx位置开始是否是byts内容
            Func <byte[], bool> eq = (byts) =>
            {
                for (var i = 0; i < byts.Length; i++, idx++)
                {
                    if (idx >= data.Length)
                    {
                        return(false);
                    }

                    if (byts[i] != data[idx])
                    {
                        return(false);
                    }
                }

                return(true);
            };


            if (pem.Contains("PUBLIC KEY"))
            {
                //使用公钥
                //读取数据总长度
                readLen(0x30);

                //看看有没有oid
                var idx2 = idx;
                if (eq(SeqOid))
                {
                    //读取1长度
                    readLen(0x03);
                    idx++; //跳过0x00
                    //读取2长度
                    readLen(0x30);
                }
                else
                {
                    idx = idx2;
                }

                //Modulus
                param.KeyModulus = readBlock();

                //Exponent
                param.KeyExponent = readBlock();
            }
            else if (pem.Contains("PRIVATE KEY"))
            {
                //使用私钥
                //读取数据总长度
                readLen(0x30);

                //读取版本号
                if (!eq(Ver))
                {
                    throw new Exception("PEM未知版本");
                }

                //检测PKCS8
                var idx2 = idx;
                if (eq(SeqOid))
                {
                    //读取1长度
                    readLen(0x04);
                    //读取2长度
                    readLen(0x30);

                    //读取版本号
                    if (!eq(Ver))
                    {
                        throw new Exception("PEM版本无效");
                    }
                }
                else
                {
                    idx = idx2;
                }

                //读取数据
                param.KeyModulus  = readBlock();
                param.KeyExponent = readBlock();
                param.KeyD        = readBlock();
                param.ValP        = readBlock();
                param.ValQ        = readBlock();
                param.ValDp       = readBlock();
                param.ValDq       = readBlock();
                param.ValInverseQ = readBlock();
            }
            else
            {
                throw new Exception("pem需要BEGIN END标头");
            }

            return(param);
        }