我正在开发一些与服务器交换XML文档的软件。服务器使用XMLDSIG对XML进行签名,客户端应在信任XML之前验证签名。我使用RSACryptoServiceProvider
来执行此操作。 XML已签名,但未加密。
我遵循以下解释的基本程序:
How to Sign XML Documents with Digital Signatures
How to Verify the Digital Signatures of XML Documents
这要求客户端软件具有可用的公钥。我希望客户端软件的分发尽可能简单,我不希望客户端必须处理证书。上面引用的这对文档方便地围绕分发公钥的主题,简单地说明用户需要具有相同的密钥"。我并不特别希望最终用户甚至意识到他们有公钥,所以要求他们乱用证书是不可能的。由于公钥是公开的,我想要做的是以某种方式将其嵌入客户端软件中。在我看来,我的选择是:
这在实践中是否可行?实现这一目标的最简单方法是什么,不需要任何用户交互或意识?
答案 0 :(得分:4)
您不必分发证书。常见方法之一是将证书包含在KeyInfo/X509Data
节点中的签名文档中。
验证可以轻松使用嵌入式证书,客户端唯一需要的基础架构元素是证书指纹和主题名称。换句话说,客户端使用包含的证书验证文档,然后轻松检查证书,主题名称和指纹。如果匹配,则假设已提供正确的证书。
在我的一个博客条目中阅读有关技术细节的更多信息(这是一个3部分的教程,因此您还可以查看所有其他条目)。无论如何,没有导入证书,也没有包含软件的证书,而是有两个字符串配置参数。
XmlDsigned文档中的嵌入式证书具有const大小,通常开销可以忽略不计。
http://www.wiktorzychla.com/2012/12/interoperable-xml-digital-signatures-c.html
http://www.wiktorzychla.com/2012/12/interoperable-xml-digital-signatures-c_20.html
答案 1 :(得分:3)
我不确定您在没有看到您的代码的情况下遇到了什么问题,但this answer from Ji Zhou可以提供帮助吗?
public static void Main()
{
try
{ //initialze the byte arrays to the public key information.
byte[] PublicKey = {214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
106,99,179,68,175,211,164,116,64,148,226,254,172,147};
//Values to store encrypted symmetric keys.
byte[] EncryptedSymmetricKey;
byte[] EncryptedSymmetricIV;
//Create a new instance of RSACryptoServiceProvider.
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
//Get an instance of RSAParameters from ExportParameters function.
RSAParameters RSAKeyInfo = RSA.ExportParameters(false);
//Set RSAKeyInfo to the public key values.
RSAKeyInfo.Modulus = PublicKey;
//Import key parameters into RSA.
RSA.ImportParameters(RSAKeyInfo);
//Create a new instance of the RijndaelManaged class.
RijndaelManaged RM = new RijndaelManaged();
//Encrypt the symmetric key and IV.
EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);
Console.WriteLine("RijndaelManaged Key and IV have been encrypted with RSACryptoServiceProvider.");
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
}
}