2012-05-22 146 views
12

我想使用PKCS#7簽署文本文件(可能是.exe文件或將來的其他內容) 並使用Java驗證簽名。在JAVA中使用PKCS#7簽名數據

  1. 我需要知道什麼?
  2. 我在哪裏可以找到API(.jar和文檔)?
  3. 爲了簽署數據和驗證數據,我需要遵循哪些步驟?

如果可能請給我提供代碼片段。

+2

尊敬的用戶,請重溫[這個舊的問題(http://stackoverflow.com/questions/9805385/delete - 查詢 - 是 - 不工作 - 成型 - Java的應用程序)。我已經投票結束了另一個問題。 [請](http://stackoverflow.com/questions/2377402/how-to-encode-a-value-in-pkcs7-with-java)[做](http://stackoverflow.com/questions/3166159/在提出問題之前驗證你的功課。 –

+0

您是否希望簽名的exe文件被Windows識別爲已簽名。 –

回答

12

我想你需要以下2個充氣城堡罐子產生PKCS7數字簽名:

  • bcprov-jdk15on-147.jar(用於JDK 1.5 - 1.7 JDK)

  • bcmail- jdk15on-147.jar(用於JDK 1.5 - 1.7 JDK)

您可以從here下載充氣城堡罐子。

您需要使用公鑰&私鑰對來設置您的密鑰庫。 您只需要私鑰就可以生成數字簽名&的公鑰來驗證它。

這裏是你如何PKCS7標誌內容(略去了異常處理):

import java.io.FileInputStream; 
import java.io.InputStream; 
import java.security.KeyStore; 
import java.security.PrivateKey; 
import java.security.Security; 
import java.security.cert.Certificate; 
import java.security.cert.X509Certificate; 
import java.util.ArrayList; 
import java.util.List; 
import org.bouncycastle.cert.jcajce.JcaCertStore; 
import org.bouncycastle.cms.CMSProcessableByteArray; 
import org.bouncycastle.cms.CMSSignedData; 
import org.bouncycastle.cms.CMSSignedDataGenerator; 
import org.bouncycastle.cms.CMSTypedData; 
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
import org.bouncycastle.operator.ContentSigner; 
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; 
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; 
import org.bouncycastle.util.Store; 
import org.bouncycastle.util.encoders.Base64; 

public final class PKCS7Signer { 

    private static final String PATH_TO_KEYSTORE = "/path/to/keyStore"; 
    private static final String KEY_ALIAS_IN_KEYSTORE = "My_Private_Key"; 
    private static final String KEYSTORE_PASSWORD = "MyPassword"; 
    private static final String SIGNATUREALGO = "SHA1withRSA"; 

    public PKCS7Signer() { 
    } 

    KeyStore loadKeyStore() throws Exception { 

     KeyStore keystore = KeyStore.getInstance("JKS"); 
     InputStream is = new FileInputStream(PATH_TO_KEYSTORE); 
     keystore.load(is, KEYSTORE_PASSWORD.toCharArray()); 
     return keystore; 
    } 

    CMSSignedDataGenerator setUpProvider(final KeyStore keystore) throws Exception { 

     Security.addProvider(new BouncyCastleProvider()); 

     Certificate[] certchain = (Certificate[]) keystore.getCertificateChain(KEY_ALIAS_IN_KEYSTORE); 

     final List<Certificate> certlist = new ArrayList<Certificate>(); 

     for (int i = 0, length = certchain == null ? 0 : certchain.length; i < length; i++) { 
      certlist.add(certchain[i]); 
     } 

     Store certstore = new JcaCertStore(certlist); 

     Certificate cert = keystore.getCertificate(KEY_ALIAS_IN_KEYSTORE); 

     ContentSigner signer = new JcaContentSignerBuilder(SIGNATUREALGO).setProvider("BC"). 
       build((PrivateKey) (keystore.getKey(KEY_ALIAS_IN_KEYSTORE, KEYSTORE_PASSWORD.toCharArray()))); 

     CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); 

     generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC"). 
       build()).build(signer, (X509Certificate) cert)); 

     generator.addCertificates(certstore); 

     return generator; 
    } 

    byte[] signPkcs7(final byte[] content, final CMSSignedDataGenerator generator) throws Exception { 

     CMSTypedData cmsdata = new CMSProcessableByteArray(content); 
     CMSSignedData signeddata = generator.generate(cmsdata, true); 
     return signeddata.getEncoded(); 
    } 

    public static void main(String[] args) throws Exception { 

     PKCS7Signer signer = new PKCS7Signer(); 
     KeyStore keyStore = signer.loadKeyStore(); 
     CMSSignedDataGenerator signatureGenerator = signer.setUpProvider(keyStore); 
     String content = "some bytes to be signed"; 
     byte[] signedBytes = signer.signPkcs7(content.getBytes("UTF-8"), signatureGenerator); 
     System.out.println("Signed Encoded Bytes: " + new String(Base64.encode(signedBytes))); 
    } 
} 
+0

我如何生成公鑰和私鑰。 什麼算法可以用來簽名。 我們沒有提到位長。 可否請您提供任何學習資料參考資料,以便我能理解a2z – user1269042

+0

@ user1269042,請參閱[公鑰密碼學](http://en.wikipedia.org/wiki/Public-key_cryptography)。谷歌周圍找到更多。儘管有點過時,[Java開始加密](http://www.amazon.com/Beginning-Cryptography-Java-David-Hook/dp/0764596330)是一個很好的參考。 – Zaki

+0

您忘記提及org.bouncycastle.cms導入時需要使用bcpkix-jdk15on-147.jar(現在爲148)。 –

4

PKCS#7現在稱爲CMS(加密消息語法),您將需要Bouncy Castle PKIX庫來創建一個。它有充足的文件和完善的郵件列表。

我不會提供代碼片斷,這是違反家庭規則的。先試試自己。

+0

當前版本被稱爲'bcpkix-jdk15on-147.jar',google它。 –

+0

非常感謝您的回覆。我會通過它 – user1269042