Как создать блок pkcs7 только для обмена ключами (надувной замок) - PullRequest
1 голос
/ 03 июля 2011

Я пытаюсь создать файл, содержащий блок pkcs 7.В этом контейнере мне нужен мой открытый ключ и информация о подписавшем (без подписанных данных !!!).Я уже попробовал несколько альтернатив без какой-либо удачи.Это мой код:

Сначала информация о подписи:

 List<X509Certificate> certs = new List<X509Certificate> { cert };
 IX509Store x509Certs = X509StoreFactory.Create(
      "CERTIFICATE/COLLECTION",
      new X509CollectionStoreParameters(certs));

 var ias = new IssuerAndSerialNumber(cert.IssuerDN, cert.SerialNumber);
 SignerIdentifier sid = new SignerIdentifier(ias);
 AlgorithmIdentifier algoDigId = new AlgorithmIdentifierCmsSignedGenerator.DigestSha1);
 AlgorithmIdentifier algoCryptId = new AlgorithmIdentifier(CmsSignedGenerator.EncryptionRsa);

 SignerInfo si = new SignerInfo(sid, algoDigId, null, algoCryptId,
                                      new DerOctetString(contentSignature), null);

Байт contentSignature [] содержит подписанный дайджест для некоторой информации.

Теперь, когда я пытаюсьсоздать SignedData, все идет не так

  var signedContent = new ContentInfo(CmsObjectIdentifiers.Data, DerNull.Instance);
  CmsSignedData csd = new CmsSignedData(signedContent);

Я не пытаюсь отправить информацию, это только для обмена ключами и проверки.Я считаю, что это правильный сценарий, но почему-то это не работает.

Спасибо за вашу помощь.

ОБНОВЛЕНИЕ:

больше контекста.

Япытается подписать JAR из исполняемого файла .Net.Я в значительной степени выполнил остальную часть процесса, но jarsigner создает файл pkcs7 с:

  • ContentInfo, установленным для типа Data и без содержимого.Пока что создание нового ContentInfo (CmsObjectIdentifiers.Data, null) просто вызывает исключение при добавлении информации о содержимом в CmsData

  • При добавлении SignerInfo эта SignerInfo включает подпись, ранее полученную изсодержание JAR.

Ответы [ 2 ]

1 голос
/ 10 августа 2011

Поскольку этот вопрос конкретно относится к подписанию файла APK / JAR, я отвечу в этом контексте.

Предполагая, что:

Вы выполнили все следующие шаги настройки:

  1. Создан действительный файл MANIFEST.MF
  2. Создан действительный CERT.SF
  3. Загрузите действительный файл PFX в переменную X509Certificate2 с именем "cert"
  4. Содержит двоичное содержимое файла CERT.SF в байтовом массиве с именем "manifestSFBytes"

Следующий код сгенерирует действительную отдельную подпись pkcs7, которая фактически является вашим содержимым CERT.RSA:

string OID_DATA = "1.2.840.113549.1.7.1";

// setup the data to sign
ContentInfo content = new ContentInfo( new Oid( OID_DATA ), manifestSFBytes );
SignedCms signedCms = new SignedCms( content, true );
CmsSigner signer = new CmsSigner( SubjectIdentifierType.IssuerAndSerialNumber, cert );

// create the signature
signedCms.ComputeSignature( signer );
byte[] data = signedCms.Encode();

Этот код основан на пространстве имен System.Security.Cryptography.Pkcs и не требует BouncyCastle.

Здесь происходит то, что необработанный контент (двоичные данные файла подписи) хэшируется и подписывается за один раз вызовом ComputeSignature ().

Поэтому трюки с «нулевым ContentInfo» не нужны, т. Е. ContentInfo содержит необработанные данные, которые должны быть подписаны и хэшированы, в отличие от реализации Java, которая подписывает и хэширует контент до генерации PKCS7.

НТН

- (е) ​​

0 голосов
/ 04 июля 2011

Вот простой пример того, что, я думаю, вы хотите сделать. Примечание: Приведенный ниже код предназначен для BouncyCastle Java, но я думаю, что классы очень похожи на C # версии библиотеки

.
import java.io.*;
import java.security.cert.*;
import java.util.ArrayList;
import java.util.List;

import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.*;

public class PKCS7CertList1
{

    public static byte[] buildCMSCertThingy() throws Exception
    {
        final List<X509Certificate> certs = new ArrayList<X509Certificate>();
        final InputStream certIs = new FileInputStream("google_com.p7b");
        final CertificateFactory cf = CertificateFactory.getInstance("X.509");
        for (Certificate cert : cf.generateCertificates(certIs))
        {
            certs.add((X509Certificate) cert);
        }
        certIs.close();
        System.err.printf("Number of certs parsed = %d%n", certs.size());
        final CMSSignedDataGenerator cmsGen = new CMSSignedDataGenerator();
        cmsGen.addCertificates(new JcaCertStore(certs));
        final CMSSignedData sigData = cmsGen.generate(new CMSAbsentContent(), false);
        return sigData.getEncoded();
    }
    public static void main(String[] args) throws Exception
    {   
        FileOutputStream fos = new FileOutputStream("signed_data.der");
        fos.write(buildCMSCertThingy());
        fos.close();
    }

}
...