【加密与解密】Openssl 生成的RSA秘钥如被C#使用解密

来源:互联网 发布:推出mac的应用程序 编辑:程序博客网 时间:2024/05/21 07:56

openssl生成的RSA公私钥对保存一个pem文件中,生成时可以选择加密与不加密,如果要提取私钥需要用到openssl rsa进行提取,之后用c#转换为xml之后再对加密数据进行解密,详细如下:

1、openssl生成秘钥

E:\bin>openssl genrs

a -aes128 -out rsakey.pem -passout pass:111111 1024
Loading 'screen' into random state - done
Generating RSA private key, 1024 bit long modulus
.........................++++++
.................................++++++
e is 65537 (0x10001)

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,80BF9FA9D86FA1F503A7CC8271A87F2C


NSh4bKCv5hv1pBDDy3hrcLG/KvLH0kIa5MJHFZz4B8D5IdlnYngIFzgFkUI23B2R
0799D0x8mIfHwjbkbflWodguL/1v17DxpDHk/DJ8uavHWuiurWnd1h3dnwPBT/Gk
XmWk8V8hq+K9LuVkOVSHZVlGBMfZiaGX1AE+keWX5Vg3zYSvYeY6l1M0xWEISkJd
yYuULM82sA1t0cPsx7uTPhxePZycxx3W8rC77xg3AMk5riEfWVmmB5JYP1GCFnqo
Ve8Emi484igfvwIKKeqGCNcenURybEPh+eu3vjwkZIQmMrBA9YXx6CSvwB+uYGjz
8uSbTp/UrYr9AklupjrARlHPux7JuAOxtqO1JzE4bgrHLdz8EOtEf6Se+41ME/dQ
/VF43JmZG+lquo3clU2R8RcXiceZoS84qcJhDI58ZymPWpPpvFc5feeuGAfyYFRB
7L+HMOfE3AYqncIFzSYwGkVKBZZhxoQWceLOp7Tb66KpiiyrS+DBB0qwO5tXRkNo
Q753z4B2RwM7reNlPrERy4dxS1iL41YOYdk0S2WebjMivUkz/hV5bl2VWgxNv87b
+wqzarBAWdeOHab1s2vbITxZLHdryj6APDtNyTLbVAGO01OeDO3oqb/kbREe3M1+
WRjTNhc7pjI9NtuZyQ2wTnsizpq/1YYmeJqBhUQVVWD+2r7cy8iPPMSyN1/7egxf
qE46H4ms40HdNnWijkBKbrM+v6VEpoNuZL74h+sNLKPLwc/onJRsnh6HLZA9KG5t
ika/Bl3K2N/16cHwdNtwfqBe5WIGpaCwrs9MPWZEl+u7te5+8MKVRkvQeMZhrTWD
-----END RSA PRIVATE KEY-----

2、私钥提取过程
E:\bin>openssl rsa -
in rsakey.pem -out rsakeydec.txt
Enter pass phrase for rsakey.pem:
writing RSA key

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCiDrABZg4R+uIqaqUl1gAaxxRJxWD77wDw1lFQR38CiwMhwaqY
6lUEwhwVGIXz6Gd2h+qgKcFlm6wcEqG6jwT5mT/IiYb6e+QrSXMkrF1KHbmKyoMq
gi3toMYS+4DvfGswm9k/8Ln9MoXzwlGliiC5Px24aT5uGsPl9LMxqGPS/wIDAQAB
AoGAYsyXi1K/00BkMD3yT13nlGu4t70JAq9UoH/Y9RuRmGhN0X+z1SRQDuWUn1vj
Fq+inEYCygCK8rp0tGy7gvR8sAKlk8yZqDJ+JyLfocNeuevAADtADxfYNE+wpVGC
s9OXCq6kN8aXFJDF9NX6KsNNUZPEKu/Kmkb7e7NaTLRtfkECQQDUcX6Wa07VFIEI
V7ONaIal2DvwpNhxWz45tFY7MFVSju622auEiRRHBm0GT7BlTHs5gVfjjrifDEjp
baSE5+ifAkEAw0iWOEvuT61lMNwpA6H0dg33ZBvGvDUePDSRHFkNGBm2rkTEvzxd
bFFxF1410lXzWGmvY4hRJIREo2+8a00ZoQJALOIFkpX9Q7tfP3n370pEGEnE8CSD
rf9O+DYHed3OSPD1sh/uwsOLSy4qXoj7hYtRBWc0QFlo3AFmbhrCBWpRlQJBAIj0
fTXaOrXye0c7ACCmEpZA0UGKIWSZNC0xCJwC8CX40p+BZyJfKX3v2Ap1bfWnhdR5
uiFp1s5vXNvqXxA5sEECQQCgc3+Qa8KLDBtLd4k95jVuGB+3KzznTTKglxoIZopd
RuBA30QczIIHwsH06khVrZYKOhgLOvNtMZMLrIDRTbLs
-----END RSA PRIVATE KEY-----

3、利用c#生成xml文件用于加密数据解密
<RSAKeyValue><Modulus>og6wAWYOEfriKmqlJdYAGscUScVg++8A8NZRUEd/AosDIcGqmOpVBMIcFR
iF8+hndofqoCnBZZusHBKhuo8E+Zk/yImG+nvkK0lzJKxdSh25isqDKoIt7aDGEvuA73xrMJvZP/C5/T
KF88JRpYoguT8duGk+bhrD5fSzMahj0v8=</Modulus><Exponent>AQAB</Exponent><P>1HF+lmtO
1RSBCFezjWiGpdg78KTYcVs+ObRWOzBVUo7uttmrhIkURwZtBk+wZUx7OYFX4464nwxI6W2khOfonw==
</P><Q>w0iWOEvuT61lMNwpA6H0dg33ZBvGvDUePDSRHFkNGBm2rkTEvzxdbFFxF1410lXzWGmvY4hRJ
IREo2+8a00ZoQ==</Q><DP>LOIFkpX9Q7tfP3n370pEGEnE8CSDrf9O+DYHed3OSPD1sh/uwsOLSy4qX
oj7hYtRBWc0QFlo3AFmbhrCBWpRlQ==</DP><DQ>iPR9Ndo6tfJ7RzsAIKYSlkDRQYohZJk0LTEInALw
JfjSn4FnIl8pfe/YCnVt9aeF1Hm6IWnWzm9c2+pfEDmwQQ==</DQ><InverseQ>oHN/kGvCiwwbS3eJP
eY1bhgftys8500yoJcaCGaKXUbgQN9EHMyCB8LB9OpIVa2WCjoYCzrzbTGTC6yA0U2y7A==</Inverse
Q><D>YsyXi1K/00BkMD3yT13nlGu4t70JAq9UoH/Y9RuRmGhN0X+z1SRQDuWUn1vjFq+inEYCygCK8rp
0tGy7gvR8sAKlk8yZqDJ+JyLfocNeuevAADtADxfYNE+wpVGCs9OXCq6kN8aXFJDF9NX6KsNNUZPEKu/
Kmkb7e7NaTLRtfkE=</D></RSAKeyValue>

请按任意键继续. . .


4、c#测试源代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using  System.IO;
using System.Security.Cryptography;
using System.ComponentModel;
using System.Runtime.InteropServices;


/*refer: http://q.cnblogs.com/q/70822/ 
 http://blog.chinaunix.net/uid-26729093-id-4449165.html*/
namespace ConsoleApplication1
{


    class Program
    {
        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;
        }


  
        public static RSACryptoServiceProvider DecodeRSAPrivateKey(string priKey)
        {
            var privkey = Convert.FromBase64String(priKey);
            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 -----
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                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 e)
            {
                Console.WriteLine(e.Message + e.StackTrace);
                return null;
            }
            finally
            {
                binr.Close();
            }
        }


        /************************************************************************/
        /* 你的是pem key,需要下转换为c# rsa provider认识的key。
            首先,干掉头部和尾部的无用字符,然后利用如下方法转换:*/
        /************************************************************************/
        public static void PrivateKeyDecFun()
        {
            string priKey = @"-----BEGIN RSA PRIVATE KEY-----
                MIICWwIBAAKBgQCf1a4LQyipBqeUCZ9kKsfasQzkEFCBmGsM21Sakb5BO0sY07GD
                cproJHF2xNQrV0cM7+liE3pBUFsarui2WaHZhAibpLbl9z4FSfoN5hSg6sEgbB17
                SvKe3ZN/75GoEsQiQtYW4gUJgzrBovVZ+TeTnN+NHHBqUqBKhNIgPFVapQIDAQAB
                AoGAG0OMs5kaF3LuJN9bU+/ENXab908dHG4OXJwRG2ie5muhzLNXhU+IQu7sd9Dt
                TBNQKFHIIpWl9fwp/iw1v90cMUQGj0zhSXHAz7Vak/ryQLTyeIIciL8MQWvnbAaN
                lIoFq2wBl7SYs3n71B4MlvvTysaG0krsjiPh5LVgnBvzjGECQQDcAwe4XnF7SHWO
                nfljrG29soKNiUhYKtDGcV9fvam9u50Ek882wvFmsJP+tk+1CXjMRSNlOi40bxKC
                uaBa1JOtAkEAufq9FmZHfBFf3e6n57wLiAj5C1MeyHAtt6qdAF49OZJBGZh1pePn
                jDGNezFvy7U5bMp7/updisLCFueS5eKB2QJAF84QIMe/OZqedZ7sI/e9LABLlerb
                tAZ17nLH4gEQg6HwHFWt3vv6yKSkbrPlLe5nbpqweLxx0WSPOSvCiPFlRQJAPAfF
                NQ+6jz+EdDxukgxOpJBQ4ujnjMc42ooFt3KzzHt66+ocP3m66bOs+VDRxy0t5gHN
                2FCJ9Ro8T+xbrDxasQJAARHpcG6tE0F+lmUthtep1U8OrF+AQvqDhBq8MYK+/pF/
                LRZkFHkqTsj89OyWDlSH3LeYkOWsr9mAFxsvHZ9BSA==
                -----END RSA PRIVATE KEY-----";




            priKey = priKey.Replace("-----BEGIN RSA PRIVATE KEY-----", "")
                .Replace("-----END RSA PRIVATE KEY-----", "");




            RSACryptoServiceProvider rsaProvider = DecodeRSAPrivateKey(priKey);
            String PrivateKey = rsaProvider.ToXmlString(true);//将RSA算法的私钥导出到字符串PrivateKey中,参数为true表示导出私钥
            Console.WriteLine(PrivateKey);
            /************************************************************************/
            /* 程序运行结果如下:
             * <RSAKeyValue><Modulus>n9WuC0MoqQanlAmfZCrH2rEM5BBQgZhrDNtUmpG+QTtLGNOxg3Ka6CRxds
                TUK1dHDO/pYhN6QVBbGq7otlmh2YQIm6S25fc+BUn6DeYUoOrBIGwde0rynt2Tf++RqBLEIkLWFuIFCY
                M6waL1Wfk3k5zfjRxwalKgSoTSIDxVWqU=</Modulus><Exponent>AQAB</Exponent><P>3AMHuF5x
                e0h1jp35Y6xtvbKCjYlIWCrQxnFfX72pvbudBJPPNsLxZrCT/rZPtQl4zEUjZTouNG8SgrmgWtSTrQ==
                </P><Q>ufq9FmZHfBFf3e6n57wLiAj5C1MeyHAtt6qdAF49OZJBGZh1pePnjDGNezFvy7U5bMp7/updi
                sLCFueS5eKB2Q==</Q><DP>F84QIMe/OZqedZ7sI/e9LABLlerbtAZ17nLH4gEQg6HwHFWt3vv6yKSkb
                rPlLe5nbpqweLxx0WSPOSvCiPFlRQ==</DP><DQ>PAfFNQ+6jz+EdDxukgxOpJBQ4ujnjMc42ooFt3Kz
                zHt66+ocP3m66bOs+VDRxy0t5gHN2FCJ9Ro8T+xbrDxasQ==</DQ><InverseQ>ARHpcG6tE0F+lmUth
                tep1U8OrF+AQvqDhBq8MYK+/pF/LRZkFHkqTsj89OyWDlSH3LeYkOWsr9mAFxsvHZ9BSA==</Inverse
                Q><D>G0OMs5kaF3LuJN9bU+/ENXab908dHG4OXJwRG2ie5muhzLNXhU+IQu7sd9DtTBNQKFHIIpWl9fw
                p/iw1v90cMUQGj0zhSXHAz7Vak/ryQLTyeIIciL8MQWvnbAaNlIoFq2wBl7SYs3n71B4MlvvTysaG0kr
                sjiPh5LVgnBvzjGE=</D></RSAKeyValue>
                  请按任意键继续. . .*/
            /************************************************************************/
        }


        public static void PrivateKeyDecFun1()
        {
            string priKey = @"MIICXQIBAAKBgQCiDrABZg4R+uIqaqUl1gAaxxRJxWD77wDw1lFQR38CiwMhwaqY
                6lUEwhwVGIXz6Gd2h+qgKcFlm6wcEqG6jwT5mT/IiYb6e+QrSXMkrF1KHbmKyoMq
                gi3toMYS+4DvfGswm9k/8Ln9MoXzwlGliiC5Px24aT5uGsPl9LMxqGPS/wIDAQAB
                AoGAYsyXi1K/00BkMD3yT13nlGu4t70JAq9UoH/Y9RuRmGhN0X+z1SRQDuWUn1vj
                Fq+inEYCygCK8rp0tGy7gvR8sAKlk8yZqDJ+JyLfocNeuevAADtADxfYNE+wpVGC
                s9OXCq6kN8aXFJDF9NX6KsNNUZPEKu/Kmkb7e7NaTLRtfkECQQDUcX6Wa07VFIEI
                V7ONaIal2DvwpNhxWz45tFY7MFVSju622auEiRRHBm0GT7BlTHs5gVfjjrifDEjp
                baSE5+ifAkEAw0iWOEvuT61lMNwpA6H0dg33ZBvGvDUePDSRHFkNGBm2rkTEvzxd
                bFFxF1410lXzWGmvY4hRJIREo2+8a00ZoQJALOIFkpX9Q7tfP3n370pEGEnE8CSD
                rf9O+DYHed3OSPD1sh/uwsOLSy4qXoj7hYtRBWc0QFlo3AFmbhrCBWpRlQJBAIj0
                fTXaOrXye0c7ACCmEpZA0UGKIWSZNC0xCJwC8CX40p+BZyJfKX3v2Ap1bfWnhdR5
                uiFp1s5vXNvqXxA5sEECQQCgc3+Qa8KLDBtLd4k95jVuGB+3KzznTTKglxoIZopd
                RuBA30QczIIHwsH06khVrZYKOhgLOvNtMZMLrIDRTbLs";


            priKey = priKey.Replace("-----BEGINENCRYPTED PRIVATE KEY-----", "")
                .Replace("-----ENDENCRYPTED PRIVATE KEY-----", "");
            DecodeRSAPrivateKey(priKey);


            RSACryptoServiceProvider rsaProvider = DecodeRSAPrivateKey(priKey);
            String PrivateKey = rsaProvider.ToXmlString(true);//将RSA算法的私钥导出到字符串PrivateKey中,参数为true表示导出私钥
            Console.WriteLine(PrivateKey);
   
 
        }


    
        static void Main(string[] args)
        {
            PrivateKeyDecFun();
            PrivateKeyDecFun1();           
            return;
        }
    }
}

5、参考文档

http://q.cnblogs.com/q/70822/
http://blog.chinaunix.net/uid-26729093-id-4449165.html

http://download.csdn.net/download/jiayanhui2877/4089521

0 0