.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");
            }

        }

    }
}
posted @ 2009-09-09 19:52  Think  阅读(7094)  评论(13编辑  收藏  举报