.NET RSACryptoServiceProvider PEM + DER Support
http://www.christian-etter.de/?p=771
In .NET, RSACryptoServiceProvider greatly simplifies common tasks associated with public/private keys, such as signing of data and verifying a signature.
Unfortunately, there is only a single format (proprietary XML) available for importing and exporting public/private key data.
The two widely spread formats for key exchange, PEM and DER are not supported, which limits the usability of the class when working with different kinds of public key APIs.
There are a few workarounds though:
- Write your own .NET code to support the desired formats, which might not be that simple, as the following blog post suggests.
- Use a third party component, such as the PEMReader class of the Bouncy Castle Library (Java/C# port).
- Leverage Microsoft Crypto API (CAPI), which provides support for opening and converting a variety of different public/private key file formats. Here I would like to demonstrate how this can be achieved by means of simple extension methods to theRSACryptoServiceProvider class.
Here is a sample RSA 1024 bit private key in PEM format:
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDwIqfvxEjqHu8048x4wJ5EId6ASAbWdH5fzgHxvew5kXqECMNc
XzRqDVnDVPQT41UeZs8HxouBE+ZA8DfnVlHwP4EIeigOUaqy0sseKpO71tupFU+2
LjpcF6O7cVuLjt6476iYfSyrssK4hnmzVYGZNz16OSR9z/SuTd8BhohG4QIDAQAB
AoGBAOmEmhEUrN9XU8D4IVfv4DhbQ1c2M8gKovYhjEx8J6LX8O9C4lAKmRrkfrzv
+Sb59EVLLtrd3b2ZD1lpAMQrciMwC5PAa8da/J++lR1VjM5GbzqKjGtfx3WQlzNE
1ZaZ2FSY8lAPMM4uLczyD79PJQBsGCcx3KDJRR5ENp6an5cRAkEA/m1FEqol/KKh
xOyGsK4GVuansBXhrAgpwMlYLT+vF0gy1jzYQDNNQXzeQFYH6gZY66RTYFl3JPNL
8KXLyhwDLQJBAPGew6xkLBoYi4IO9I+NP/gIHzSiQeEl2OxZsgZiz0Yh5E9ndwMr
87jTX/4ZBwNlDC0E+MXsJpMSvTFNpw4rcwUCQQC5FU5JLKOjq79YnOPChWYxM2vL
Ka/YULvm9dGCYTCDFE9/EBYUZf2OZULctHjfYqyvBwRsM8j7hU26CzI7nbMlAkAA
kVjwXMPlw80AHzzf4XsXAB3ip8bz2nzqAUPz0+OczJOWxC15am8GLij5leF4VpJy
wKI9BNMKYW7kYMRVujBpAkEA7gQ8MGqjjrCAfOzrrC9ZuVdGRfEjUEdHMqiF+js7
XNBvnT5lBznUOd+eta6CGo7S5hjU7D3CEzmVGQfxUsRZ1w==
-----END RSA PRIVATE KEY-----
This is the corresponding public key in textual PEM representation:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDwIqfvxEjqHu8048x4wJ5EId6A
SAbWdH5fzgHxvew5kXqECMNcXzRqDVnDVPQT41UeZs8HxouBE+ZA8DfnVlHwP4EI
eigOUaqy0sseKpO71tupFU+2LjpcF6O7cVuLjt6476iYfSyrssK4hnmzVYGZNz16
OSR9z/SuTd8BhohG4QIDAQAB
-----END PUBLIC KEY-----
We cannot load these keys into the RSACryptoServiceProvider directly. However the class supports an import method which is compatible with CryptoAPI: ImportCspBlob().
With CAPI in return, we can do all the heavy lifting including format conversion which the .NET Framework does not support.
For public keys, the conversion process for PEM (string) key data requires the following steps:
- Converting a public key in PEM string format into DER representation.
CryptStringToBinaryA( sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, IntPtr.Zero, ref dwBinarySize, out dwSkip, out dwFlags ) )
- Retrieve the key through a CERT_PUBLIC_KEY_INFO struct.
CryptDecodeObjectEx( CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr( (int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO ), DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, ref pCertPublicKeyInfo, out dwCertPublicKeyInfoSize )
- Convert the returned RSA key into a Diffie-Hellman Version 3 Public Key BLOBs or DSS Version 3 Public Key BLOBs struct:
CryptDecodeObjectEx( CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr( (int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB ), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, ref pCertPublicKeyBlob, out dwCertPublicKeyBlobSize )
- Call RSACryptoServiceProvider.ImportCspBlob() for the resulting binary data.
For private keys, the following steps are required:
- Converting a private key in PEM string format into DER representation.
CryptStringToBinaryA( sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, IntPtr.Zero, ref dwBinarySize, out dwSkip, out dwFlags ) )
- For private keys, retrieve a pointer to an RSA private key BLOB directly:
CryptDecodeObjectEx( CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr( (int)CRYPT_OUTPUT_TYPES.PKCS_RSA_PRIVATE_KEY ), DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.CRYPT_DECODE_ALLOC_FLAG, IntPtr.Zero, ref pRSAPrivateKeyBlob, out pRSAPrivateKeyBlobSize )
- Call RSACryptoServiceProvider.ImportCspBlob() for the resulting binary data.
If you wrap the above logic into extension methods for RSACryptoServiceProvider, importing keys in PEM format and signing data can be done with a few lines of code:
// -----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY----- |
Verifying the same signature also becomes easy:
// -----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY----- |
Here is a cut-and-paste solution based on an extension class to RSACryptoServiceProvider:
/********************************************************************************* |
I am attaching a Visual Studio 2012 solution containing a sample usage for PEM and DER encoded files. Click here to download.
Solution containing sample keys:
Test program output:
.NET RSACryptoServiceProvider PEM + DER Support的更多相关文章
- 那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)[zz]
openssl dgst –sign privatekey.pem –sha1 –keyform PEM –c c:\server.pem 将文件用sha1摘要,并用privatekey.pem中的私 ...
- 那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)
之前没接触过证书加密的话,对证书相关的这些概念真是感觉挺棘手的,因为一下子来了一大堆新名词,看起来像是另一个领域的东西,而不是我们所熟悉的编程领域的那些东西,起码我个人感觉如此,且很长时间都没怎么搞懂 ...
- OpenSSL使用2(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12概念说明)(转)
SSL SSL - Secure Sockets Layer,现在应该叫"TLS",但由于习惯问题,我们还是叫"SSL"比较多.http协议默认情况下是不加密内 ...
- 那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)(使用OpenSSL的命令行)
之前没接触过证书加密的话,对证书相关的这些概念真是感觉挺棘手的,因为一下子来了一大堆新名词,看起来像是另一个领域的东西,而不是我们所熟悉的编程领域的那些东西,起码我个人感觉如此,且很长时间都没怎么搞懂 ...
- curl 使用手册
curl.1 the man page Related: Manual FAQ HTTP Scripting NAME curl - transfer a URL SYNOPSIS curl [opt ...
- 关于x509、crt、cer、key、csr、pem、der、ssl、tls 、openssl等
关于x509.crt.cer.key.csr.pem.der.ssl.tls .openssl等 TLS:传输层安全协议 Transport Layer Security的缩写 TLS是传输层安全协议 ...
- 全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件
作者: zyl910 一.缘由 RSA是一种常用的非对称加密算法.所以有时需要在不用编程语言中分别使用RSA的加密.解密.例如用Java做后台服务端,用C#开发桌面的客户端软件时. 由于 .Net.J ...
- How to convert .crt to .pem [duplicate]证书转化
openssl x509 -in mycert.crt -out mycert.pem -outform PEM openssl x509 -inform DER -in yourdownloaded ...
- wpa_supplicant.conf
转自:http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=blob_plain;f=wpa_supplicant/wpa_supplicant.conf ### ...
随机推荐
- json-c-0.9 的简单用法
1.下载安装包路径: wget http://oss.metaparadigm.com/json-c/json-c-0.9.tar.gz 2.解压安装包 tar zxvf json-c-0.9.tar ...
- I.MX6 32G SD卡测试
/*********************************************************************** * I.MX6 32G SD卡测试 * 说明: * 这 ...
- cron用法
cron用法说明 cron的用法老是记不住,索性写下来备忘.下文内容大部分是根据<Cron Help Guide>翻译而来,有些部分是自己加上的. 全文如下: cron来源于希腊单词chr ...
- php中将url中的参数含有%20进行转换或解码
我的url: .......index.php?action=search&start=12&search=star wave&orderby=categories&s ...
- 一个for列出横纵坐标
h = i % * hCount; v = Math.floor(i / hCount);
- php二分式查找
要求数组是有序数组 1 <?php 2 #二分查找 3 function binarySearch(Array $arr, $target) { 4 $low = 0; 5 $high = co ...
- 227. Basic Calculator II
Implement a basic calculator to evaluate a simple expression string. The expression string contains ...
- List-ApI及详解
1.API : add(Object o) remove(Object o) clear() indexOf(Object o) get(int i) size() iterator() isEmpt ...
- C++ Primer : 第十二章 : 动态内存之shared_ptr类实例:StrBlob类
StrBlob是一个管理string的类,借助标准库容器vector,以及动态内存管理类shared_ptr,我们将vector保存在动态内存里,这样就能在多个对象之间共享内存. 定义StrBlob类 ...
- SQL参数化查询--最有效可预防SQL注入攻击的防御方式
参数化查询(Parameterized Query 或 Parameterized Statement)是访问数据库时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值. 在使用参 ...