예제 #1
0
        static void RSATest()
        {
            var rsa = new RSA(512);

            Console.WriteLine("【" + rsa.KeySize + "私钥(XML)】:");
            Console.WriteLine(rsa.ToXML());
            Console.WriteLine();
            Console.WriteLine("【" + rsa.KeySize + "私钥(PEM)】:");
            Console.WriteLine(rsa.ToPEM_PKCS1());
            Console.WriteLine();
            Console.WriteLine("【" + rsa.KeySize + "公钥(PEM)】:");
            Console.WriteLine(rsa.ToPEM_PKCS1(true));
            Console.WriteLine();

            var str = "abc内容123";
            var en  = rsa.Encode(str);

            Console.WriteLine("【加密】:");
            Console.WriteLine(en);

            Console.WriteLine("【解密】:");
            Console.WriteLine(rsa.DecodeOrNull(en));

            Console.WriteLine("【签名SHA1】:");
            Console.WriteLine(rsa.Sign("SHA1", str));
            Console.WriteLine();

            var rsa2 = new RSA(rsa.ToPEM_PKCS8(), true);

            Console.WriteLine("【用PEM新创建的RSA是否和上面的一致】:");
            Console.WriteLine("XML:" + (rsa2.ToXML() == rsa.ToXML()));
            Console.WriteLine("PKCS1:" + (rsa2.ToPEM_PKCS1() == rsa.ToPEM_PKCS1()));
            Console.WriteLine("PKCS8:" + (rsa2.ToPEM_PKCS8() == rsa.ToPEM_PKCS8()));

            var rsa3 = new RSA(rsa.ToXML());

            Console.WriteLine("【用XML新创建的RSA是否和上面的一致】:");
            Console.WriteLine("XML:" + (rsa3.ToXML() == rsa.ToXML()));
            Console.WriteLine("PKCS1:" + (rsa3.ToPEM_PKCS1() == rsa.ToPEM_PKCS1()));
            Console.WriteLine("PKCS8:" + (rsa3.ToPEM_PKCS8() == rsa.ToPEM_PKCS8()));

            //--------RSA_PEM验证---------
            RSA_PEM pem = rsa.ToPEM();

            Console.WriteLine("【RSA_PEM是否和原始RSA一致】:");
            Console.WriteLine(pem.KeySize + "位");
            Console.WriteLine("XML:" + (pem.ToXML(false) == rsa.ToXML()));
            Console.WriteLine("PKCS1:" + (pem.ToPEM(false, false) == rsa.ToPEM_PKCS1()));
            Console.WriteLine("PKCS8:" + (pem.ToPEM(false, true) == rsa.ToPEM_PKCS8()));
            Console.WriteLine("仅公钥:");
            Console.WriteLine("XML:" + (pem.ToXML(true) == rsa.ToXML(true)));
            Console.WriteLine("PKCS1:" + (pem.ToPEM(true, false) == rsa.ToPEM_PKCS1(true)));
            Console.WriteLine("PKCS8:" + (pem.ToPEM(true, true) == rsa.ToPEM_PKCS8(true)));

            var rsa4 = new RSA(new RSA_PEM(pem.Key_Modulus, pem.Key_Exponent, pem.Key_D));

            Console.WriteLine("【用n、e、d构造解密】");
            Console.WriteLine(rsa4.DecodeOrNull(en));
        }
예제 #2
0
        /// <summary>
        /// 将XML格式密钥转成PEM,支持公钥xml、私钥xml
        /// 出错将会抛出异常
        /// </summary>
        static public RSA_PEM FromXML(string xml)
        {
            RSA_PEM rtv = new RSA_PEM();

            Match xmlM = xmlExp.Match(xml);

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

            Match 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.Key_Modulus = val; break;

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

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

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

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

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

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

                case "InverseQ": rtv.Val_InverseQ = val; break;
                }
                tagM = tagM.NextMatch();
            }

            if (rtv.Key_Modulus == null || rtv.Key_Exponent == null)
            {
                throw new Exception("XML公钥丢失");
            }
            if (rtv.Key_D != null)
            {
                if (rtv.Val_P == null || rtv.Val_Q == null || rtv.Val_DP == null || rtv.Val_DQ == null || rtv.Val_InverseQ == null)
                {
                    return(new RSA_PEM(rtv.Key_Modulus, rtv.Key_Exponent, rtv.Key_D));
                }
            }

            return(rtv);
        }
예제 #3
0
파일: RSA.cs 프로젝트: oujunke/RSA-csharp
 /// <summary>
 /// 通过一个pem对象创建RSA,pem为公钥或私钥,出错抛异常
 /// </summary>
 public RSA(RSA_PEM pem)
 {
     rsa = pem.GetRSA();
 }
예제 #4
0
파일: RSA.cs 프로젝트: oujunke/RSA-csharp
 /// <summary>
 /// 通过一个pem文件创建RSA,pem为公钥或私钥,出错抛异常
 /// </summary>
 public RSA(string pem, bool noop)
 {
     rsa = RSA_PEM.FromPEM(pem).GetRSA();
 }
예제 #5
0
        /// <summary>
        /// 用PEM格式密钥对创建RSA,支持PKCS#1、PKCS#8格式的PEM
        /// 出错将会抛出异常
        /// </summary>
        static public RSA_PEM FromPEM(string pem)
        {
            RSA_PEM param = new RSA_PEM();

            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++]);
                    }
                    else if (data[idx] == 0x82)
                    {
                        idx++;
                        return((((int)data[idx++]) << 8) + data[idx++]);
                    }
                    else 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);

                //检测PKCS8
                var idx2 = idx;
                if (eq(_SeqOID))
                {
                    //读取1长度
                    readLen(0x03);
                    idx++;                    //跳过0x00
                    //读取2长度
                    readLen(0x30);
                }
                else
                {
                    idx = idx2;
                }

                //Modulus
                param.Key_Modulus = readBlock();

                //Exponent
                param.Key_Exponent = 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.Key_Modulus  = readBlock();
                param.Key_Exponent = readBlock();
                int keyLen = param.Key_Modulus.Length;
                param.Key_D        = BigL(readBlock(), keyLen);
                keyLen             = keyLen / 2;
                param.Val_P        = BigL(readBlock(), keyLen);
                param.Val_Q        = BigL(readBlock(), keyLen);
                param.Val_DP       = BigL(readBlock(), keyLen);
                param.Val_DQ       = BigL(readBlock(), keyLen);
                param.Val_InverseQ = BigL(readBlock(), keyLen);
            }
            else
            {
                throw new Exception("pem需要BEGIN END标头");
            }

            return(param);
        }