使用Base64编码的公钥来validationRSA签名

简而言之,这是我的问题:

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

如您所见,问题是使用给定的Base64编码公钥字符串启动新的RSACryptoServiceProvider。 我已经能够使用对象RSAParameters进行实例化,该对象使用OpenSSL shell命令从用于此公钥字符串的Modulus和Exponent加载byte []。 但由于此公钥可能在将来发生变化,因此我希望能够将其以原始forms存储在数据库中。 必须有一种更直接的方法来解决这个问题。

到目前为止,我读过的很多例子都是通过将生成的私钥和公钥导入和导出密钥容器对象并在同一段代码中使用它来避免这个问题,因此不会“转移”密钥。一些字符串forms内存不足。 有些人在StackOverflow和其他网站上都表达了同样的问题,但我还没有找到令人满意的答案。

任何想法都非常受欢迎。

背景信息:我的通信伙伴从可变长度的输入字符串计算一个20字节的SHA1哈希值,该字符串由ASCII编码消息的几个字段中包含的信息组成。 然后使用我的合作伙伴的私钥对此哈希进行RSA签名,并将ASCII消息一起发送给我。 到达后,我自己计算SHA1哈希,使用ASCII消息中的相同字段,然后尝试通过调用VerifyHash来validation这些字段是否未被更改。

密钥以两种forms提供:常规和“noNL”。 noNL版本包含在上面的代码中,常规版本是这样的:

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

您的字符串是SubjectPublicKeyInfo的base64编码。 你可以使用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); 

第一个base64只是一些二进制数据的编码。 以二进制方式编码RSA公钥的方法不止一种。 但是,如果从OpenSSL获得此信息,则可能是DER编码的RSAPublicKey结构。

  RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n publicExponent INTEGER } -- e 

一般来说,你需要一个ASN.1解码器, Mono.Security.dll提供一个 ,但是对于这样一个简单的结构你可能想手工完成,因为ASN.1基本上是一个标签长度和一个