17

SHA256 アルゴリズムを使用して xml ドキュメントに署名するために使用する SigningCredentials オブジェクトを作成するコードがあります。.NET 3.5 で完全に動作します。ただし、コードベースを .NET 4.5 にアップグレードすると、動作しなくなります。同じコード、同じ証明書! 私は何時間もデバッグとインターネットでの検索に何時間も費やしました。

ここで何が問題なのか誰か教えてください。前もって感謝します。

SigningCredentials を作成するコード:

public SigningCredentials CreateSigningCredentials(X509Certificate2 cert)
{
    var ski = new SecurityKeyIdentifier(new X509RawDataKeyIdentifierClause(cert));
    return new SigningCredentials(new X509AsymmetricSecurityKey(cert), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "http://www.w3.org/2001/04/xmlenc#sha256", ski);
}

例外:

[CryptographicException: Invalid algorithm specified.
]
   System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) +41
   System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature) +0
   System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash) +118
   System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash) +334
   System.Security.Cryptography.RSAPKCS1SignatureFormatter.CreateSignature(Byte[] rgbHash) +321
   System.IdentityModel.SignedXml.ComputeSignature(HashAlgorithm hash, AsymmetricSignatureFormatter formatter, String signatureMethod) +323
   System.IdentityModel.SignedXml.ComputeSignature(SecurityKey signingKey) +690
   System.IdentityModel.EnvelopedSignatureWriter.ComputeSignature() +338
   System.IdentityModel.EnvelopedSignatureWriter.OnEndRootElement() +278
   System.IdentityModel.Metadata.MetadataSerializer.WriteEntityDescriptor(XmlWriter inputWriter, EntityDescriptor entityDescriptor) +1109
4

3 に答える 3

16

XmlDsig にも同じ問題がありました (RSA-SHA256 アルゴリズムを使用して xml ドキュメントのエンベロープ署名を作成しようとしています)。最初に例外が発生していました

System.Security.Cryptography.CryptographicException: 提供された署名アルゴリズムに対して SignatureDescription を作成できませんでした。

次にRSAPKCS1SHA256SignatureDescription、RSA-SHA256署名の署名記述実装についての言及を見つけました。
ここでの完全な実装:
http://clrsecurity.codeplex.com/SourceControl/changeset/view/47833#269110
またはここ: https://gist.github.com/sneal/f35de432115b840c4c1f

appdomain ごとに 1 回手動で呼び出す必要があります。

CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

その後、私は新しい例外を得ました:

System.Security.Cryptography.CryptographicException: 無効なアルゴリズムが指定されました。

これは私にあなたの質問をもたらしました。提案された記事を読んだ後、を使用して新しいキーと証明書 (OpenSSL を使用) を作成しMicrosoft Enhanced RSA and AES Cryptographic Providerました。
驚いたことに、この新しい証明書により、署名を成功させることができました。

さらに調査した結果、Andrew の興味深い回答がhttps://stackoverflow.com/a/17285774/328785で見つかりました。ここで、彼はクラスRSACryptoServiceProviderの SecretKey を準備していました。SignedXml具体的にはこの部分(私の解釈):

var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
var certificates =  store.Certificates.Find(X509FindType.FindBySerialNumber,  "54dba096", true);
var certificate = certificates[0];

// next three lines
var cspParams = new CspParameters(24) { KeyContainerName = "XML_DSIG_RSA_KEY" };
var key = new RSACryptoServiceProvider(cspParams);
key.FromXmlString(certificate.PrivateKey.ToXmlString(true));

SignedXml sxml = new SignedXml(doc);
sxml.SigningKey = key;

そして、このソリューションは古いキーでも問題なく機能しました!

于 2015-02-25T12:02:25.163 に答える