.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 ### ...
随机推荐
- CSS 实现:图片+文字的布局(综合)
☊[实现要求]:图片+文字+居中 √[实现]: ① img + 文字 <div class="demo2-1"> <img src="" al ...
- Apache CXF 103 CXF Basics - partial
本Spike记录中内容,如无特别指出,均引用[1]. 0 引言 0.1 基本的Web服务术语 XML 业界的结构化交换信息表示的事实上的标准. XML namespace是在XML文档中提供唯一的命名 ...
- 转载:奇异值分解(SVD) --- 线性变换几何意义(下)
本文转载自他人: PS:一直以来对SVD分解似懂非懂,此文为译文,原文以细致的分析+大量的可视化图形演示了SVD的几何意义.能在有限的篇幅把这个问题讲解的如此清晰,实属不易.原文举了一个简单的图像处理 ...
- 发布常见问题(C#)
1.Sys.WebForms.PageRequestManagerServerErrorException: 在服务器上处理请求时出现未知错误.服务器返回的状态码为: 500 可能的原因: asp.n ...
- 2016 Sichuan Province Programming Contest
2016 Sichuan Province Programming Contest 代码 2016 Sichuan Province Programming Contest A. Nearest Ne ...
- wamp2.4允许局域网访问,如Android模拟器和手机
Apache 从2.2升级到 Apache2.4.x 后配置文件 httpd.conf 的设置方法有了大变化,以前是将 deny from all 全部改成 Allow from all 实现外网访问 ...
- java中将汉字转换成16进制
技术交流群:233513714 /** * 将汉字转换车16进制字符串 * @param str * @return st */ public static String enUnicode(Stri ...
- [CTSC 2012][BZOJ 2806]Cheat
真是一道好题喵~ 果然自动机什么的就是要和 dp 搞基才是王道有木有! A:连 CTSC 都叫我们搞基,果然身为一个程序猿,加入 FFF 团是我此生最明智的选择.妹子什么闪边去,大家一起来搞基吧! Q ...
- 黑马程序员——JAVA基础之主函数main和静态static,静态代码块
------- android培训.java培训.期待与您交流! ---------- 主函数:是一个特殊的函数.作为程序的入口,可以被jvm调用. 主函数的定义: public:代表着该函数访问权限 ...
- java的nio之:浅析I/O模型
也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗.在 进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型.下面本文先从同步和异步的概念 说起 ...