使用Base64编码的公钥验证RSA签名 [英] Using Base64 encoded Public Key to verify RSA signature

查看:259
本文介绍了使用Base64编码的公钥验证RSA签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

概括地说,这是我的问题:

 私人字符串publicKeyString = MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVGUzbydMZS + fnkGTsUkDKEyFOGwghR234d5GjPnMIC0RFtXtw2tdcNM8I9Qk + h6fnPHiA7r27iHBfdxTP3oegQJWpbY2RMwSmOs02eQqpKx4QtIjWqkKk2Gmck5cll9GCoI8AUAA5e0D02T0ZgINDmo5yGPhGAAmqYrm8YiupwQIDAQAB; 

*使用publicKeyString启动一个新的RSACryptoServiceProvider对象
* /

//现在需要一些转换:
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider ();

byte [] selfComputedHash = new byte []; //不在示例中
byte [] signature = new byte [];

bool result = rsa.VerifyHash(selfComputedHash,CryptoConfig.MapNameToOID(SHA1),signature);

正如您所看到的,问题是使用给定的Base64编码的公钥字符串启动新的RSACryptoServiceProvider。我已经能够使用对象RSAParameters进行实例化,该对象使用OpenSSL shell命令从此公钥字符串派生出来的Modulus和Exponent加载到byte []中。但是由于这个公钥可能会在将来发生变化,我希望能够将它以原始形式存储在数据库中。



到目前为止,我读过的很多例子都是通过导出和导入生成的私有和公共文件来避免这个问题键和键容器对象之间的键,并将其用于同一段代码中,因此不会以某种字符串形式将密钥传送出内存不足。有些人在StackOverflow和其他网站上都表达了相同的问题,但我还没有找到令人满意的答案。



任何想法都超过

背景信息:
我的通信伙伴从一个可变长度的输入字符串中计算出一个20字节的SHA1哈希, ASCII编码消息的字段。然后这个哈希值与我的合作伙伴的私钥进行RSA签名,并与ASCII消息一起发送给我。抵达后,我自己计算SHA1哈希,使用ASCII消息中的相同字段,然后尝试验证这些字段是否未通过调用VerifyHash进行更改。



密钥以两种形式提供:普通和'noNL'。 noNL版本包含在上面的代码中,常规版本如下: ---
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVGUzbydMZS + fnkGTsUkDKEyFO
GwghR234d5GjPnMIC0RFtXtw2tdcNM8I9Qk + h6fnPHiA7r27iHBfdxTP3oegQJWp
bY2RMwSmOs02eQqpKx4QtIjWqkKk2Gmck5cll9GCoI8AUAA5e0D02T0ZgINDmo5y
GPhGAAmqYrm8YiupwQIDAQAB
----- END PUBLIC KEY -----


解决方案

您的字符串是 SubjectPublicKeyInfo 。您可以使用 Bouncycastle.net 来解码它:

  byte [] publicKeyBytes = Convert.FromBase64String(publicKeyString); 
AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(publicKeyBytes);
RsaKeyParameters rsaKeyParameters =(RsaKeyParameters)asymmetricKeyParameter;
RSAParameters rsaParameters = new RSAParameters();
rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParameters);


In a nutshell, this is my problem:

private string publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVGUzbydMZS+fnkGTsUkDKEyFOGwghR234d5GjPnMIC0RFtXtw2tdcNM8I9Qk+h6fnPHiA7r27iHBfdxTP3oegQJWpbY2RMwSmOs02eQqpKx4QtIjWqkKk2Gmck5cll9GCoI8AUAA5e0D02T0ZgINDmo5yGPhGAAmqYrm8YiupwQIDAQAB";

/* Some transformation required, using publicKeyString to initiate a new RSACryptoServiceProvider object
*/

//for now:
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

byte[] selfComputedHash = new byte[]; //left out of the example
byte[] signature = new byte[];

bool result = rsa.VerifyHash(selfComputedHash, CryptoConfig.MapNameToOID("SHA1"), signature);

As you can see, the problem is initiating a new RSACryptoServiceProvider with the given Base64 encoded public key string. I've been able to do the instantiation using an object RSAParameters, loaded with the byte[]'s for Modulus and Exponent derived from this public key string using an OpenSSL shell command. But since this public key may change in the future I want to be able to store it in its original form in a database. There must be a more straightforward way of dealing with this.

A lot of the examples I've read so far avoid this problem by exporting and importing the generated private and public keys to and from a key-container object and use it in the same piece of code and thus not 'transferring' the key in some string form out of memory. Some people have expressed the same problem, both here on StackOverflow and on other sites, but I have not been able to find a satisfying answer yet.

Any idea's are more than welcome.

Background info: My communication partner computes a 20-byte SHA1-hash from an input string of variable length, composed of the information contained in several fields of an ASCII encoded message. This hash is then RSA-signed with my partner's private key and sent along with the ASCII message to me. Upon arrival, I compute the SHA1 hash myself, using the same fields from the ASCII message and then try to verify if these fields were not altered by calling VerifyHash.

The key is provided in 2 forms: regular and 'noNL'. The noNL version is included in the code above, the regular version is this:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVGUzbydMZS+fnkGTsUkDKEyFO
GwghR234d5GjPnMIC0RFtXtw2tdcNM8I9Qk+h6fnPHiA7r27iHBfdxTP3oegQJWp
bY2RMwSmOs02eQqpKx4QtIjWqkKk2Gmck5cll9GCoI8AUAA5e0D02T0ZgINDmo5y
GPhGAAmqYrm8YiupwQIDAQAB
-----END PUBLIC KEY-----

解决方案

Your string is the base64 encoding of a SubjectPublicKeyInfo. You can use Bouncycastle.net to decode it like this:

byte[] publicKeyBytes = Convert.FromBase64String(publicKeyString);
AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(publicKeyBytes);
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters) asymmetricKeyParameter;
RSAParameters rsaParameters = new RSAParameters();
rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParameters);

这篇关于使用Base64编码的公钥验证RSA签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆