Подписание данных с помощью файла p12 / pfx в .Net - произошла внутренняя ошибка цепочки сертификатов - PullRequest
2 голосов
/ 24 февраля 2012

Я пытаюсь перенести некоторый Java-код на C #, и у меня возникла проблема с подписью данных. Я получаю сообщение об ошибке: " Произошла внутренняя ошибка цепочки сертификатов. "

Код успешно выполняется в Java на моем компьютере, но не в C #.

Ниже приведен мой код C #, который выдает исключение для ComputeSignature:

 //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();

Заранее благодарим за любую помощь, которую вы можете предложить.

EDIT Теперь у меня это работает, но мой код должен был значительно измениться. Я автоматически преобразовал код Java, чтобы увидеть, что генерируется. Результат ниже, однако это делает определенные предположения об использовании Crypto Algo. :-

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));

1 Ответ

1 голос
/ 24 февраля 2012

Похоже, что первый сертификат (к которому вы обращаетесь в C #) - это не тот сертификат, который вы ожидаете - это не сертификат конечного объекта с закрытым ключом, а промежуточный или корневой CA.Следовательно, класс подписавшего не может использовать его для подписи.Самый простой подход для проверки правильности предположения состоит в том, чтобы попробовать все сертификаты в коллекции и посмотреть, работает ли кто-нибудь из них.

...