我终于想通了。诀窍是注册XML签名指定的算法,在我的情况下”
http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1
“.将其注册到自定义类,该类使用自定义签名格式化程序和变形程序
RSASignaturePadding.Pss
.
下面是一个实现,您只需调用
RsaSsaPss.RegisterSha256RsaMgf1()
一次,例如从客户端的静态构造函数。然后
SignedXml.CheckSignature()
和
SignedXml.ComputeSignature()
自动适用于指定此算法的任何XML签名。
在核心2.1和框架4.7.1上测试:
public class RsaSsaPss
{
public static void RegisterSha256RsaMgf1()
{
CryptoConfig.AddAlgorithm(typeof(RsaPssSha256SignatureDescription), "http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1");
}
public class RsaPssSha256SignatureDescription : SignatureDescription
{
public RsaPssSha256SignatureDescription()
{
using (var rsa = RSA.Create())
{
this.KeyAlgorithm = rsa.GetType().AssemblyQualifiedName;
}
this.DigestAlgorithm = "SHA256";
this.FormatterAlgorithm = typeof(RsaPssSignatureFormatter).FullName;
this.DeformatterAlgorithm = typeof(RsaPssSignatureDeformatter).FullName;
}
public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
{
var signatureFormatter = new RsaPssSignatureFormatter();
signatureFormatter.SetKey(key);
signatureFormatter.SetHashAlgorithm(this.DigestAlgorithm);
return signatureFormatter;
}
public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
{
var signatureDeformatter = new RsaPssSignatureDeformatter();
signatureDeformatter.SetKey(key);
signatureDeformatter.SetHashAlgorithm(this.DigestAlgorithm);
return signatureDeformatter;
}
public class RsaPssSignatureFormatter : AsymmetricSignatureFormatter
{
private RSA Key { get; set; }
private string HashAlgorithmName { get; set; }
public override void SetKey(AsymmetricAlgorithm key)
{
this.Key = (RSA)key;
}
public override void SetHashAlgorithm(string strName)
{
Oid.FromFriendlyName(strName, OidGroup.HashAlgorithm);
this.HashAlgorithmName = strName;
}
public override byte[] CreateSignature(byte[] rgbHash)
{
return this.Key.SignHash(rgbHash, new HashAlgorithmName(this.HashAlgorithmName), RSASignaturePadding.Pss);
}
}
public class RsaPssSignatureDeformatter : AsymmetricSignatureDeformatter
{
private RSA Key { get; set; }
private string HashAlgorithmName { get; set; }
public override void SetKey(AsymmetricAlgorithm key)
{
this.Key = (RSA)key;
}
public override void SetHashAlgorithm(string strName)
{
Oid.FromFriendlyName(strName, OidGroup.HashAlgorithm);
this.HashAlgorithmName = strName;
}
public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
{
return this.Key.VerifyHash(rgbHash, rgbSignature, new HashAlgorithmName(this.HashAlgorithmName), RSASignaturePadding.Pss);
}
}
}
}