zoukankan      html  css  js  c++  java
  • .NET使用OpenSSL生成的pem密钥文件【做电子商务的朋友可能需要】


    .NET要使用OpenSSL生成的pem密钥文件,网上资料很少(http://www.faqs.org/rfcs/rfc1421.html,RFC1421文件又老长老长),仅有的资料还是有错误的,所以今天干了件体力活,把PEM密钥文件610个字节一个个看过来,终于搞清了它的格式。(欢迎转载,注明出处:http://thinhunan.cnblogs.com)

    增加了2048位密钥支持的类在:

    .NET使用OpenSSL生成的pem密钥文件(增加size为2048的密钥转换)【做电子商务的朋友可能需要】


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

    namespace Thinhunan.Cnblogs.Com.RSAUtility
    {
        
    public class PemConverter
        {
            
    /// <summary>
            
    /// 将pem格式公钥转换为RSAParameters
            
    /// </summary>
            
    /// <param name="pemFileConent">pem公钥内容</param>
            
    /// <returns>转换得到的RSAParamenters</returns>
            public static RSAParameters ConvertFromPemPublicKey(string pemFileConent)
            {
                
    if (string.IsNullOrEmpty(pemFileConent))
                {
                    
    throw new ArgumentNullException("pemFileConent""This arg cann't be empty.");
                }
                pemFileConent 
    = pemFileConent.Replace("-----BEGIN PUBLIC KEY-----""").Replace("-----END PUBLIC KEY-----""").Replace("\n""").Replace("\r""");
                
    byte[] keyData = Convert.FromBase64String(pemFileConent);
                
    if (keyData.Length < 162)
                {
                    
    throw new ArgumentException("pem file content is incorrect.");
                }
                
    byte[] pemModulus = new byte[128];
                
    byte[] pemPublicExponent = new byte[3];
                Array.Copy(keyData, 
    29, pemModulus, 0128);
                Array.Copy(keyData, 
    159, pemPublicExponent, 03);
                RSAParameters para 
    = new RSAParameters();
                para.Modulus 
    = pemModulus;
                para.Exponent 
    = pemPublicExponent;
                
    return para;
            }

            
    /// <summary>
            
    /// 将pem格式私钥转换为RSAParameters
            
    /// </summary>
            
    /// <param name="pemFileConent">pem私钥内容</param>
            
    /// <returns>转换得到的RSAParamenters</returns>
            public static RSAParameters ConvertFromPemPrivateKey(string pemFileConent)
            {
                
    if (string.IsNullOrEmpty(pemFileConent))
                {
                    
    throw new ArgumentNullException("pemFileConent""This arg cann't be empty.");
                }
                pemFileConent 
    = pemFileConent.Replace("-----BEGIN RSA PRIVATE KEY-----""").Replace("-----END RSA PRIVATE KEY-----""").Replace("\n""").Replace("\r","");
                
    byte[] keyData = Convert.FromBase64String(pemFileConent);
                
    if (keyData.Length < 609)
                {
                    
    throw new ArgumentException("pem file content is incorrect.");
                }

                
    int index = 11;
                
    byte[] pemModulus = new byte[128];
                Array.Copy(keyData, index, pemModulus, 
    0128);

                index 
    += 128;
                index 
    += 2;//141
                byte[] pemPublicExponent = new byte[3];
                Array.Copy(keyData, index, pemPublicExponent, 
    03);

                index 
    += 3;
                index 
    += 4;//148
                byte[] pemPrivateExponent = new byte[128];
                Array.Copy(keyData, index , pemPrivateExponent, 
    0128);

                index 
    += 128;
                index 
    += ((int)keyData[index+1== 64?23);//279
                byte[] pemPrime1 = new byte[64];
                Array.Copy(keyData, index, pemPrime1, 
    064);

                index 
    += 64;
                index 
    += ((int)keyData[index + 1== 64 ? 2 : 3);//346
                byte[] pemPrime2 = new byte[64];
                Array.Copy(keyData, index , pemPrime2, 
    064);

                index 
    += 64;
                index 
    += ((int)keyData[index + 1== 64 ? 2 : 3);//412/413
                byte[] pemExponent1 = new byte[64];
                Array.Copy(keyData,index, pemExponent1, 
    064);

                index 
    += 64;
                index 
    += ((int)keyData[index + 1== 64 ? 2 : 3);//479/480
                byte[] pemExponent2 = new byte[64];
                Array.Copy(keyData, index, pemExponent2, 
    064);

                index 
    += 64;
                index 
    += ((int)keyData[index + 1== 64 ? 2 : 3);//545/546
                byte[] pemCoefficient = new byte[64];
                Array.Copy(keyData, index, pemCoefficient, 
    064);

                RSAParameters para 
    = new RSAParameters();
                para.Modulus 
    = pemModulus;
                para.Exponent 
    = pemPublicExponent;
                para.D 
    = pemPrivateExponent;
                para.P 
    = pemPrime1;
                para.Q 
    = pemPrime2;
                para.DP 
    = pemExponent1;
                para.DQ 
    = pemExponent2;
                para.InverseQ 
    = pemCoefficient;
                
    return para;
            }
            
        }
    }

    测试pem导成RSAParameters成功,使用通过:
    using System;
    using System.Security.Cryptography;
    using System.Text;
    using System.IO;
    using System.Web;


    namespace Thinhunan.Cnblogs.Com.RSAUtility
    {
        
    class Program
        {
            
    #region keys

            
    const string PUBLICKEY =
    @"-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpsDr+W45aFHIkvotZaGK/THlF
    FpuZfUtghhWkHAm3H7yvL42J4xHrTr6IeUDCl4eKe6qiIgvYSNoL3u4SERGOeYmV
    1F+cocu9IMGnNoicbh1zVW6e8/iGT3xaYQizJoVuWA/TC/zdds2ihCJfHDBDsouO
    CXecPapyWCGQNsH5sQIDAQAB
    -----END PUBLIC KEY-----
    ";


            
    const string PRIVATEKEY =
    @"-----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQDpsDr+W45aFHIkvotZaGK/THlFFpuZfUtghhWkHAm3H7yvL42J
    4xHrTr6IeUDCl4eKe6qiIgvYSNoL3u4SERGOeYmV1F+cocu9IMGnNoicbh1zVW6e
    8/iGT3xaYQizJoVuWA/TC/zdds2ihCJfHDBDsouOCXecPapyWCGQNsH5sQIDAQAB
    AoGBAM/JbFs4y5WbMncrmjpQj+UrOXVOCeLrvrc/4kQ+zgCvTpWywbaGWiuRo+cz
    cXrVQ6bGGU362e9hr8f4XFViKemDL4SmJbgSDa1K71i+/LnnzF6sjiDBFQ/jA9SK
    4PYrY7a3IkeBQnJmknanykugyQ1xmCjbuh556fOeRPaHnhx1AkEA/flrxJSy1Z+n
    Y1RPgDOeDqyG6MhwU1Jl0yJ1sw3Or4qGRXhjTeGsCrKqV0/ajqdkDEM7FNkqnmsB
    +vPd116J6wJBAOuNY3oOWvy2fQ32mj6XV+S2vcG1osEUaEuWvEgkGqJ9co6100Qp
    j15036AQEEDqbjdqS0ShfeRSwevTJZIap9MCQCeMGDDjKrnDA5CfB0YiQ4FrchJ7
    a6o90WdAHW3FP6LsAh59MZFmC6Ea0xWHdLPz8stKCMAlVNKYPRWztZ6ctQMCQQC8
    iWbeAy+ApvBhhMjg4HJRdpNbwO6MbLEuD3CUrZFEDfTrlU2MeVdv20xC6ZiY3Qtq
    /4FPZZNGdZcSEuc3km5RAkApGkZmWetNwDJMcUJbSBrQMFfrQObqMPBPe+gEniQq
    Ttwu1OULHlmUg9eW31wRI2uiXcFCJMHuro6iOQ1VJ4Qs
    -----END RSA PRIVATE KEY-----
    ";

            
    #endregion

            
    static void Main(string[] args)
            {            
                
                TestSignAndVerify();
                
            }



            
    public static void TestSignAndVerify()
            {
                
    //sign
                RSAParameters para = PemConverter.ConvertFromPemPrivateKey(PRIVATEKEY);
                RSACryptoServiceProvider rsa 
    = new RSACryptoServiceProvider();
                rsa.ImportParameters(para);
                
    byte[] testData = Encoding.UTF8.GetBytes("hello");
                MD5CryptoServiceProvider md5 
    = new MD5CryptoServiceProvider();
                
    byte[] signData = rsa.SignData(testData, md5);

                
    //verify
                RSAParameters paraPub = PemConverter.ConvertFromPemPublicKey(PUBLICKEY);
                RSACryptoServiceProvider rsaPub 
    = new RSACryptoServiceProvider();
                rsaPub.ImportParameters(paraPub);
                
    if (rsaPub.VerifyData(testData, md5, signData))
                {
                    Console.WriteLine(
    "ok");
                }
                
    else
                {
                    Console.WriteLine(
    "no");
                }

            }

        }
    }
  • 相关阅读:
    ESXI | ESXI6.7如何在网页端添加用户并且赋予不同的权限 风行天下
    网页前端 风行天下
    Zabbix远程命令权限不足问题解决方法 风行天下
    CentOS 8时间同步 风行天下
    linux之mv命令排除某个文件或文件夹 风行天下
    zabbix已是运行状态但zabbix server is not running解决办法 风行天下
    centos7进入救援模式,修复错误配置 风行天下
    Centos7 rsync 实现文件同步 风行天下
    python基础之socket与socketserver 风行天下
    linux中命令cp复制拷贝访问权限和修改时间 风行天下
  • 原文地址:https://www.cnblogs.com/think/p/ConvertPem2RSAParemeters.html
Copyright © 2011-2022 走看看