如何使用私钥对XML文件签名并返回签名?

问题描述 投票:-1回答:1

请帮助我解决以下问题:我有一个关于Java的代码Java代码下面:

StringBuilder fullText;
KeyStore p12 = KeyStore.getInstance("PKCS12");
p12.load(new FileInputStream("FileName.p12"), "1234".toCharArray());

Key key = (Key) p12.getKey("1", "1234".toCharArray());

//signing
Signature signer = Signature.getInstance("SHA1withRSA");

signer.initSign((PrivateKey) key);
signer.update(fullText.toString().getBytes());
b`yte[] digitalSignature = signer.sign();

String base64sign = new String(Base64.getEncoder().encode(digitalSignature));

我试图在.Net平台上复制它。我在.NET 3.5平台上创建代码。 X ++上的代码如下:

public static boolean Encrypt(str sXmlDoc)
{
    boolean bSuccess = false;

    System.Security.Cryptography.X509Certificates.X509Certificate2 p12;
    System.Security.Cryptography.AsymmetricAlgorithm key;

    str sBase64Cert;
    str sBase64Xml;
    str sBase64Sign;

    str sTmp;

    System.Byte[] byteArray;
    System.Security.Cryptography.Xml.Signature signer;
    System.Exception  ex;
    str sKeyPublic;
    System.Byte[] keyPublic;
    System.Int32 myInt32;
    int myInt;
    System.Byte[] byteTmp, byteTmp2;
    System.Text.ASCIIEncoding txtEncoder;
    System.Security.Cryptography.Xml.KeyInfo keyInfo;
    System.Security.Cryptography.Xml.SignedXml signedXml;
    System.Xml.XmlDocument xmlDocument;
    System.Xml.XmlElement xmlElement;
    System.Security.Cryptography.Xml.SignedInfo signedInfo;
    System.Security.Cryptography.Xml.Reference reference;
    System.Security.Cryptography.Xml.XmlDsigEnvelopedSignatureTransform env;

    System.Security.Cryptography.Xml.RSAKeyValue rsaKeyValue;
    System.Security.Cryptography.RSA rsaKey;

    try
    {


        p12 = new System.Security.Cryptography.X509Certificates.X509Certificate2("fileName.p12", "pass");
        if (p12)
        {
            //Signature

            //TEST
            if (p12.get_HasPrivateKey())
            {
                key = p12.get_PrivateKey();
                rsaKey = p12.get_PrivateKey();

                xmlDocument = new System.Xml.XmlDocument();
                xmlDocument.set_PreserveWhitespace(true); //Allow white spaces
                xmlDocument.LoadXml(sXmlDoc);
                signedXml = new System.Security.Cryptography.Xml.SignedXml(xmlDocument);
                signedXml.set_SigningKey(key);
                keyInfo = new System.Security.Cryptography.Xml.KeyInfo();
                rsaKeyValue = new System.Security.Cryptography.Xml.RSAKeyValue(rsaKey);
                keyInfo.AddClause(rsaKeyValue);
                signedXml.set_KeyInfo(keyInfo);
                // Create a reference to be signed.
                //System.Security.Cryptography.Xml.Reference reference;
                reference = new System.Security.Cryptography.Xml.Reference();
                reference.set_Uri("");
                // Add an enveloped transformation to the reference.
                env = new System.Security.Cryptography.Xml.XmlDsigEnvelopedSignatureTransform();
                reference.AddTransform(env);
                // Add the reference to the SignedXml object.
                signedXml.AddReference(reference);
                signedXml.set_KeyInfo(keyInfo);
                signedXml.ComputeSignature();
                xmlElement = signedXml.GetXml();
                signer = new System.Security.Cryptography.Xml.Signature();
                signer = signedXml.get_Signature();
                signedInfo = new System.Security.Cryptography.Xml.SignedInfo();
                signedInfo = signer.get_SignedInfo();
                byteTmp = signer.get_SignatureValue();
                sTmp = System.Convert::ToBase64String(byteTmp);
                sBase64Sign = "<signature>"+sTmp+"</signature>";
                info(sBase64Sign);
            }
        }

    }
    catch (Exception::CLRError)
    {
        ex = ClrInterop::getLastException();
        if (ex != null)
        {
           ex = ex.get_InnerException();
           if (ex != null)
           {
               error(ex.ToString());
           }
        }
    }

    return bSuccess;
}

但是结果与我在Java上得到的结果不同。我打开了p12键。我签署了XML字符串并获得了该XML的签名,但是得到了错误的字符串。我做错了什么?

java cryptography .net-3.5 signature x++
1个回答
0
投票

Java代码没有说任何有关XML的信息,所以我不知道您是否了解有关移植代码的任何知识,但是如果您确实在C#中使用XML,那么它将失败。

简而言之,您需要直接使用RSA函数。在大多数语言中,以RSA.Create()开头可能很有意义。但是,.NET而是基于证书/密钥的(无论好坏,您执行操作on密钥而不是using密钥,并且私钥被视为它们所属证书的一部分)” 。因此,使用RSA.Create()可能是一个更好的起点。

这就是本小教程的全部内容。我一秒钟都不相信您认为您的代码将是正确的端口,所以从头开始。编程愉快。


[编辑:哦,最后一个提示:SHA1withRSA是使用PKCS#1 v1.5填充进行签名生成的RSA,使用SHA-1作为基础哈希函数(当然,它是SHATTERED等等)。

© www.soinside.com 2019 - 2024. All rights reserved.