2011-07-03 20 views
1

我正在嘗試創建一個包含pkcs 7塊的文件。在這個容器中,我需要我的公鑰和我的簽名者信息(沒有簽名的數據!!!)。我已經嘗試了幾種選擇,但沒有任何運氣。這是我的代碼:如何創建僅用於密鑰交換的pkcs7塊(充氣城堡)

首先簽名信息:

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的byte []包含已簽名的消化一段信息。

現在,當我嘗試創建簽名數據,一切都下山

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

我沒有嘗試發送信息,這只是針對密鑰交換和驗證。我相信這是一個有效的情況,但不知何故,這是行不通的。

感謝您的幫助。

更新:

更多上下文。

我想從.net可執行文件簽名JAR。我已經幾乎完成了過程的其餘部分,但的jarsigner創建PKCS7文件有:

  • ContentInfo組輸入數據和沒有內容。到目前爲止,在將內容信息添加到CmsData時,使新的ContentInfo(CmsObjectIdentifiers.Data,null)僅引發異常。添加SignerInfo時,此SignerInfo包含先前從JAR內容派生的簽名。

+0

請添加詳細信息的聲明 「......沒有任何的運氣」。 –

+0

請在下面看到我的評論(我不小心將它作爲答案,對不起) – Flaker

+0

@GregS我已經添加了更多信息的問題。 BTW我沒有看到.Net端口中的CMSAbsentContent類。我會看看Java版本,看看它是什麼。 – Flaker

回答

1

由於此問題與簽署APK/JAR文件具體相關,因此我將在該上下文中回答。

假設:

您已執行以下所有設置步驟:

  1. 產生有效的MANIFEST.MF
  2. 生成有效CERT.SF
  3. 有一個有效的PFX文件加載寫入名爲「cert」的X509Certificate2變量
  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包含待簽名和散列的原始數據,這與在PKCS7生成之前簽署和散列內容的Java實現不同。

HTH

- (E)

0

這是我認爲你想要做的一個簡單的例子。注意:下面的代碼適用於Java bouncycastle,但我認爲這些類在庫的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(); 
    } 

}