c# - 在 .Net 中使用 p12/pfx 文件签署数据 - 发生内部证书链接错误

标签 c# encryption cryptography x509 x509certificate2

我正在尝试将一些 Java 代码移植到 C#,但在签署数据时遇到了问题。我收到的错误是“发生内部证书链错误。

代码在我机器上的 java 中运行成功,但在 C# 中运行失败。

下面是我在 ComputeSignature 上抛出异常的 C# 代码:

 //Import the certificate
        var certificate2Collection = new X509Certificate2Collection();
        certificate2Collection.Import(certificateFilePath, "**password**", X509KeyStorageFlags.DefaultKeySet);

        //Only one cert in pks file
        var cert2 = certificate2Collection[0];

        //create data to be signed
        var time = DateTime.Now.ToString("dd/MM/yyyy") + " 00:00:00";
        var modifiedTimestamp = userName + "|" + time;
        var dataToSign = Encoding.ASCII.GetBytes(modifiedTimestamp);

        var content = new ContentInfo(dataToSign);
        var signedMessage = new SignedCms(content);

        var cmsSigner = new CmsSigner(cert2);
        signedMessage.**ComputeSignature**(cmsSigner);

        byte[] signedBytes = signedMessage.Encode();

        string signedData = Convert.ToBase64String(signedBytes);

这是有效的java代码:

        final String time = new java.text.SimpleDateFormat("dd/MM/yyyy").format(new java.util.Date());

    final String timestamp = time + " 00:00:00";

    // Create the data to be signed
    final String modifiedTimestamp = userName + "|" + timestamp;
    final byte[] ba = modifiedTimestamp.getBytes();

    final byte[] signedData; 

    final KeyStore ks = KeyStore.getInstance(certificateStoreType);

    ks.load(certificateStream, certificatePassword);

    // Get the certificate from the keystore using the alias            
    final X509Certificate inCert = (X509Certificate) ks.getCertificate(certificateAlias == null ? userName : certificateAlias);

    // Get the private key using the alias and the password            
    final PrivateKey privateKey = (PrivateKey) ks.getKey(keyAlias == null ? userName : keyAlias, certificatePassword);

    // Get the algorithm name from the certificate            
    final String issuerSigAlg = inCert.getSigAlgName();

    // Get the signature for the specified algorithm            
    final Signature sig = Signature.getInstance(issuerSigAlg);

    // Sign the message           
    sig.initSign(privateKey);            
    sig.update(ba);            
    signedData = sig.sign();

在此先感谢您提供的任何帮助。

编辑 我现在可以正常工作,但我的代码必须进行重大更改。我已经自动转换了 Java 代码以查看生成的内容。结果如下,但是这确实对所使用的加密算法做出了某些假设。:-

var buffer = new byte[fs.Length];
            fs.Read(buffer, 0, (int) fs.Length);
            var certificate2 = new X509Certificate2(buffer, certificatePassword);

            string timestamp = DateTime.Now.ToShortDateString() + " 00:00:00";
            string modifiedTs = userName + "|" + timestamp;

            var cryptoKey = new RSACryptoServiceProvider();
            var formatter = new RSAPKCS1SignatureFormatter(cryptoKey);
            formatter.SetKey(certificate2.PrivateKey);
            formatter.SetHashAlgorithm("SHA1");
            var bytes = Encoding.UTF8.GetBytes(modifiedTs);
            var rgbBytes = new SHA1CryptoServiceProvider().ComputeHash(bytes);
            string signature = Convert.ToBase64String(formatter.CreateSignature(rgbBytes));

最佳答案

看起来第一个证书(您在 C# 中访问)不是您期望的证书 - 不是带有私钥的最终实体证书,而是中间或根 CA。因此签名者类不能使用它进行签名。检查假设是否正确的最简单方法是尝试收集所有证书,看看它们是否有效。

关于c# - 在 .Net 中使用 p12/pfx 文件签署数据 - 发生内部证书链接错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9428629/

相关文章:

c# - Visual Studio 组件设计器可以访问和修改项目 .config 文件吗?

c# - 如何将索引字段添加到 Linq 结果

python - 使用子进程在python 3中使用GPG加密文件

c++ - 如何生成伪随机 32 字节字符串以用作加密哈希函数中的盐?

c# - 在 .Net Core 中使用 X509 证书对字节数组进行签名

python - 如何解密柱状转置密码

c# - 在 Mac OS X 中运行 Mono 应用程序

c# - 从给定的 url 文件夹路径的 azure 存储中获取文件名

php - Mysql 使用具有二进制数据类型的 where 子句

java - 错误 : javax. crypto.BadPaddingException:解密时填充 block 损坏