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

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, 0, 128);
            Array.Copy(keyData, 159, pemPublicExponent, 0, 3);
            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, 0, 128);

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

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

index += 128;
            index += ((int)keyData[index+1] == 64?2: 3);//279
            byte[] pemPrime1 = new byte[64];
            Array.Copy(keyData, index, pemPrime1, 0, 64);

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

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

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

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

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

}

}
}

作者 THINK(谭振林)

.NET使用OpenSSL生成的pem密钥文件的更多相关文章

  1. .NET使用OpenSSL生成的pem密钥文件[1024位]

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

  2. PHP通过OpenSSL生成证书、密钥并且加密解密数据,以及公钥,私钥和数字签名的理解

    一.公钥加密假设一下,我找了两个数字,一个是1,一个是2.我喜欢2这个数字,就保留起来,不告诉你们(私钥),然后我告诉大家,1是我的公钥. 我有一个文件,不能让别人看,我就用1加密了.别人找到了这个文 ...

  3. 使用阿里云生成的pem密钥登录

    我用的阿里云生成的ssh密钥,服务器上已有公钥,私钥为.pem文件,下载在本地,网上都说要转换为.ppk再用,其实用secure不必转换 一..pem和.ppk文件区别 .pem 密钥通用格式  .p ...

  4. openssl pem密钥文件rsa加密解密例子

    准备工作 命令行加密解密,用与比对代码中的算法和命令行的算法是否一致 C:\openssl_test>openssl rsautl -encrypt -in data.txt -inkey pu ...

  5. 使用openssl生成RSA公私密钥

    在windows 环境下 1.进入cmd命令窗口 切换到openssl程序目录下 2.输入openssl.exe,进入openssl命令模式下 3.生成私钥输入“genrsa -out app_pri ...

  6. 使用openssl 生成RSA pem格式的公钥私钥

    1.生存私钥 openssl genrsa -des3 -out private_key.pem 1024 2.生成公钥 openssl rsa -in private_key.pem -pubout ...

  7. 一个完整的类用来读取OpenSSL生成的pem格式的x509证书

    internal static class CcbRsaHelper { private const string Begin = "-----BEGIN "; private c ...

  8. 一个完整的类用来读取OpenSSL生成的pem格式的x509证书(C#)

    internal static class CcbRsaHelper { private const string Begin = "-----BEGIN "; private c ...

  9. 转换java keytools的keystore证书到OPENSSL的PEM格式文件

    背景:原先业务使用的前端为haproxy,直接端口转发至tomcat,后端进行ssl连接,所以当时生成的步骤如下 ? 1 2 •生成密钥对:keytool -genkey -alias tomcat- ...

随机推荐

  1. jquery ui tab标签

    <!DOCTYPE html> <html> <head> <title>tab</title> <style type=" ...

  2. NIO中Selector分析

        NIO中,使用Selector.select()方法来侦听是否有数据可以读/写,服务端开始执行时,如果没有客户端,这里的语句将进行阻塞,等待下面三个情况出现,才会进行后续的方法之行,这里是重点 ...

  3. dubbo管理控制台安装和使用

    dubbo管理控制台安装和使用 标签: dubbo 2014-08-19 16:31 2436人阅读 评论(1) 收藏 举报  分类: dubbo(6)  版权声明:本文为博主原创文章,未经博主允许不 ...

  4. hexo —— 简单、快速、强大的Node.js静态博客框架

    hexo是一款基于Node.js的静态博客框架.目前在GitHub上已有1375 star 和 219 fork. 特性 风一般的速度 Hexo基于Node.js,支持多进程,几百篇文章也可以秒生成. ...

  5. elfutils-libelf由于依赖而安装失败

    在Redhat安装Oracles前需要按照依赖包,但是在安装elfutils-libelf遇到了两个包相互依赖的情况 [root@rhvm1 /]# rpm -i elfutils-libelf-de ...

  6. C#使用FtpWebRequest上传文件

    System.Net命名空间下的FtpWebRequest类实现了ftp协议的.Net实现. FtpWebRequest.KeepAlive指定在请求完成后服务器是否要马上关闭连接 FtpWebReq ...

  7. 目标检测的图像特征提取之(一)HOG特征(转载)

    目标检测的图像特征提取之(一)HOG特征 zouxy09@qq.com http://blog.csdn.net/zouxy09 1.HOG特征: 方向梯度直方图(Histogram of Orien ...

  8. jQuery弹出层始终垂直居中相对于屏幕或当前窗口

    把弹出层的位置设为fixed,设置top:50%,然后获取当前元素的整体的高度height,用获取的高度height/2,设置margin-top:-height/2.即可把当前的弹出层始终垂直居中于 ...

  9. c#部分---用函数的四种格式做一元二次方程

    格式一:(无参无返) public void fangcheng() { Console.WriteLine("请输入a的值"); double a = int.Parse(Con ...

  10. Codeforces Round #132 (Div. 2)

    A. Bicycle Chain 统计\(\frac{b_j}{a_i}\)最大值以及个数. B. Olympic Medal \(\frac{m_{out}=\pi (r_1^2-r_2^2)hp_ ...