文章内容

2017/4/6 14:15:40,作 者: 黄兵

C# RSA PEM解密字符

1、第一步先用openssl将pem的key转换为der的key //bin>openssl.exe rsa -in rsakeydec.pem -outform der -out pri.der 
2、调用下面的程序直接读取der转换为c#所需要的xml Key,之后进行密文解密 

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace ConsoleApplication3 {


    class Program {
        private static int GetIntegerSize(BinaryReader binr) {
            int count;
            var 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) {
                var highbyte = binr.ReadByte();
                var 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;
        }


        /// <summary>
        /// e.g:"D:\\pri.der";
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static RSACryptoServiceProvider DecodeRsaPrivateKey(string filePath) {

            byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;

            FileStream fs = new FileStream(filePath,FileMode.Open,FileAccess.Read);

            BinaryReader binr = new BinaryReader(fs);    //wrap Memory Stream with BinaryReader for easy reading
            try {
                var 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;
                var bt = binr.ReadByte();
                if(bt != 0x00)
                    return null;

                var 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();
            }
        }

        /// <summary>
        /// 导出私钥XML解密格式
        /// </summary>
        /// <returns></returns>
        public static string  PrivateKeyDecXml() {
            RSACryptoServiceProvider rsaProvider = DecodeRsaPrivateKey(@"D:\\pri.der");
            var privateKey = rsaProvider.ToXmlString(true);
            return privateKey;
        }


        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="privatekey"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string RsaDecrypt(string privatekey,string content) {

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            byte[] cipherbytes;
            rsa.FromXmlString(privatekey);
            cipherbytes = rsa.Decrypt(Convert.FromBase64String(content),false);

            return Encoding.UTF8.GetString(cipherbytes);
        }

    

        static void Main(string[] args) {
        
        var str= PrivateKeyDecXml();

            var s = RsaDecrypt(str,
                "jB6EKo9Oakc8MYMlKorZmj415+s8Qf1sHr1MIPjZcybaFhRQDVb+MBZ734p45lc2RlEJUDsy5HRH8I4LvcGSNE0kJu+ge2yy9E8xOD3dWUTU9/30vv7cEbQ5WSHtjl0MyvhTX51x3vrW/oqubH0H3p827GF3c+ALPlxrvG1gHTc=");
        }
    }
}

本文转载自:ザ紫鱼(Tiler)ザ

分享到:

发表评论

评论列表