当前位置: 首页 > 知识库问答 >
问题:

XML签名可以使用随机RSA密钥,但不能使用来自证书的密钥

爱唯
2023-03-14

我正在尝试使用C#中的以下算法对XML文档进行签名:

http://www.w3.org/2001/04/xmldsig-more#rsa-sha256

当我尝试用随机的RSA密钥签名时,它工作得很好。

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.PreserveWhitespace = false;
        xmlDoc.Load("hpbtest.xml");
        RSA Key = new RSACryptoServiceProvider(2048);
        // Create a SignedXml object.
        PrefixedSignedXML signedXml = new PrefixedSignedXML(xmlDoc);
        // Add the key to the SignedXml document.
        signedXml.SigningKey = Key;
        signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
        // Create a reference to be signed.
        Reference reference = new Reference();
        reference.Uri = "#xpointer(//*[@authenticate='true'])";
        reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
        // Add an enveloped transformation to the reference.
        XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();
        env.Algorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
        reference.AddTransform(env);
        // Add the reference to the SignedXml object.
        signedXml.AddReference(reference);
        // Compute the signature.
        signedXml.ComputeSignature("ds");
        // Get the XML representation of the signature and save
        // it to an XmlElement object.
        XmlElement xmlDigitalSignature = signedXml.GetXml("ds");
        // Append the element to the XML document.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
        xmlDoc.Save("hpbtest.xml");
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.PreserveWhitespace = false;
        xmlDoc.Load("hpbtest.xml");
        RSA Key = new GestionCertificat("CN=Bruno").getClePrivee();//Get the private key
        // Create a SignedXml object.
        PrefixedSignedXML signedXml = new PrefixedSignedXML(xmlDoc);
        // Add the key to the SignedXml document.
        signedXml.SigningKey = Key;
        signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
        // Create a reference to be signed.
        Reference reference = new Reference();
        reference.Uri = "#xpointer(//*[@authenticate='true'])";
        reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
        // Add an enveloped transformation to the reference.
        XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();
        env.Algorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
        reference.AddTransform(env);
        // Add the reference to the SignedXml object.
        signedXml.AddReference(reference);
        // Compute the signature.
        signedXml.ComputeSignature("ds");
        // Get the XML representation of the signature and save
        // it to an XmlElement object.
        XmlElement xmlDigitalSignature = signedXml.GetXml("ds");
        // Append the element to the XML document.
        xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
        xmlDoc.Save("hpbtest.xml");

谢谢你!

托马斯

共有1个答案

葛玉堂
2023-03-14

我终于找到了解决我问题的办法。如果它能帮助某人:

以前我试图通过以下方式从证书中获取私钥:

RSA Key = new GestionCertificat("CN=EbicsAuth").getClePrivee();//Get the private key

这是我的类GestionCertificat的代码:

String CertificatEncoded;
    String ModulusEncoded;
    String ExponentEncoded;
    RSA Cle;
    RSA ClePrivee;
    X509Certificate2 Certificat;
    public GestionCertificat(String NomCertificat)
    {
        X509Store store = new X509Store(StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection certCollection = store.Certificates;
        X509Certificate2 cert = null;
        foreach (X509Certificate2 c in certCollection)
        {
            if (c.Subject == NomCertificat)
            {
                cert = c;
                break;
            }
        }
        store.Close();
        Certificat = cert;
        CertificatEncoded = Convert.ToBase64String(cert.RawData); //Conversion du certificat en base64
        RSACryptoServiceProvider rsaprovider = (RSACryptoServiceProvider)cert.PublicKey.Key;//Récupération de la clé RSA du certificat
        RSAParameters newparams = rsaprovider.ExportParameters(false);//Extractions des paramètres de la clé
        ModulusEncoded = Convert.ToBase64String(newparams.Modulus);//Conversion du Modulus en base64
        ExponentEncoded = Convert.ToBase64String(newparams.Exponent);//Conversion de l'Exponent en base64
        Cle = (RSA)cert.PublicKey.Key;
        ClePrivee = (RSA)cert.PrivateKey;
    }

    public String getCertificatEncoded()
    {
        return this.CertificatEncoded;
    }

    public String getModulusEncoded()
    {
        return this.ModulusEncoded;
    }

    public String getExponentEncoded()
    {
        return this.ExponentEncoded;
    }

    public RSA getClePublique()
    {
        return this.Cle;
    }

    public RSA getClePrivee()
    {
        return this.ClePrivee;
    }

    public X509Certificate2 getCertificat()
    {
        return this.Certificat;
    }

但是现在为了获得RSA密钥来签署XML,我执行了以下操作:

RSACryptoServiceProvider Key = new RSACryptoServiceProvider();
var gestionCertif = new GestionCertificat("CN=EbicsAuth");
X509Certificate2 Cert = gestionCertif.getCertificat();
Key.FromXmlString(Cert.PrivateKey.ToXmlString(true));

现在签名起作用了!

 类似资料:
  • 看看PayPal(https://www.PayPal.com/)的安全证书。它说:连接加密:高级加密(TLS_RSA_WITH_AES_256_CBC_SHA,256位密钥)。 现在,我如何创建自己签名的证书,使其具有相同的加密,AES256? 我在OpenSSL中尝试了以下代码: 最后我得到了128位证书。然后我试着: 即使我指定了'-aes256',我最终还是得到了128位证书:连接加密:高

  • 我正在尝试从不同订阅下的密钥库安装证书。 我的VMSS在订阅xxxx下,启用了托管标识,并且在不同订阅中的密钥库的访问策略中添加了资源ID。有可能做到这一点吗?如果我能补充更多的细节,请让我知道。

  • 问题内容: 我正在编写一个用于传输文件的小型应用程序,或多或少地将其作为一种学习更多编程加密基础的方法。这个想法是生成一个RSA密钥对,交换公共密钥,并发送AES iv和密钥以进一步解密。我想用接收者的RSA公钥加密AES密钥,如下所示: 然后,我将密钥值写给接收器,并按如下方式解密: 在控制台的另一端,我将其作为输出: 此外,如果我创建一个大小为16的字节数组,并将cipher.doFinal(

  • 我可以不更新应用当我有密钥库吗?

  • 在许多网站和教科书中,他们说公钥总是用来加密,私钥是用来解密的。在RSA算法中,这是真的。但在数字签名中,发送者使用他的私钥对文档签名(我相信这有点类似于加密,如果这是错误的,请纠正我),接收者使用文档中包含的公钥对文档进行解密(验证)。那么,根据我们的应用,这可以概括为公/私钥既可以用于加密,也可以用于解密吗?还是这里涉及了其他的概念?

  • 我在.NET Core2.0中创建了一个RSA加密/解密服务,目前我使用密钥库机密来保存RSA密钥。但据我所知,我可以用Key Vault密钥实现这一点,但目前还不能实现,因为KV Keys不支持2048长RSA密钥的加密/解密...这真让我摸不着头脑。 那么,我是否可以使用带有Azure Key Vault密钥的2048密钥来实现RSA加密/解密呢?