.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 ### ...
随机推荐
- java 基本类型
1 常量 整数 byte 1字节 8位 -27~27-1 0111 1111 ~1000 0000 short 2 16 int 4 32 long 8 64 1111 111 ...
- Python 如何跳出多重循环
Python 如何跳出多重循环 抛异常 return
- The Hidden Pitfalls of AsyncTask
http://logc.at/2011/11/08/the-hidden-pitfalls-of-asynctask/
- iOS学习笔记---oc语言第六天
Block .数组高级 block本质上就是匿名函数(没有名称的函数) block语法和函数指针很相似 回顾函数 函数:C语⾔中,实现某一类功能的代码段. 完整的函数包含两部分:函数声明.函数定义 函 ...
- UVa 1592 数据库(c++pair)
Input Input contains several datasets. The first line of each dataset contains two integer numbersn ...
- java 日期格式 毫秒
参考URL:http://www.busfly.net/csdn/post/java_string_fomat_date_time_simpledateformat.html 关键代码: java.t ...
- leetcode 38 Count and Say ---java
这道题主要就是求一个序列,题目得意思就是 1 --> 11 --> 21 --> 1211 --> 111221 --> 312211 --> ..... 1个 ...
- URAL 2034 Caravans(变态最短路)
Caravans Time limit: 1.0 secondMemory limit: 64 MB Student Ilya often skips his classes at the unive ...
- 自定义颜色显示的CheckBox
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Java——日期格式
/* * 日期对象和毫秒值之间的转换. * * 毫秒值--->日期对象: * 1.通过Date对象的构造方法new Date(timeMillis) * 2.还可以通过setTime设 ...