簡體   English   中英

使用Base64編碼的公鑰來驗證RSA簽名

[英]Using Base64 encoded Public Key to verify RSA signature

簡而言之,這是我的問題:

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 []。 但由於此公鑰可能在將來發生變化,因此我希望能夠將其以原始形式存儲在數據庫中。 必須有一種更直接的方式來解決這個問題。

到目前為止,我讀過的很多例子都是通過從密鑰容器對象導出和導入生成的私鑰和公鑰來避免這個問題,並在同一段代碼中使用它,因此不會“轉移”密鑰一些字符串形式的內存不足。 有些人在StackOverflow和其他網站上都表達了同樣的問題,但我還沒有找到令人滿意的答案。

任何想法都非常受歡迎。

背景信息:我的通信伙伴從可變長度的輸入字符串計算一個20字節的SHA1哈希值,該字符串由ASCII編碼消息的幾個字段中包含的信息組成。 然后使用我的合作伙伴的私鑰對此哈希進行RSA簽名,並將ASCII消息一起發送給我。 到達后,我自己計算SHA1哈希,使用ASCII消息中的相同字段,然后嘗試通過調用VerifyHash來驗證這些字段是否未被更改。

密鑰以兩種形式提供:常規和“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基本上是一個標簽長度和一個

如果您的合作伙伴也使用.NET,他/她可以從Mono的makecert https://github.com/mono/mono/blob/bf55818da11240bd108dc51b374fae3d3b5482ce/mcs/tools/security/makecert.cs派生出來生成證書文件並直接發送給您。

在這種情況下,您可以輕松加載證書而不是原始字節,

http://www.lextm.com/2012/02/simple-publicprivate-key-signing-sample-code/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM