2012-06-22 73 views
-3

我應該寫入文件,以驗證簽名,當我們使用下面的類 簽約數據org.bouncycastle.cms.CMSSignedDataorg.bouncycastle.cms.CMSSignedDataGeneratorPKCS#7簽名

什麼

非常感謝

我已經寫代碼來實現這一點,但我得到異常

public class T2 { 
    public static String ROOT_ALIAS = "root"; 
    public static String INTERMEDIATE_ALIAS = "intermediate"; 
    public static String END_ENTITY_ALIAS = "end"; 
    public static String PLAIN_TEXT = "Hello World!123"; 
    private static final char[] KEY_PASSWORD = "keyPassword".toCharArray(); 

    public static CMSSignedData signData(KeyStore keyStore, 
      byte[] plainTextToSign) throws Exception { 
     // GET THE PRIVATE KEY 
     PrivateKey key = (PrivateKey) keyStore.getKey(END_ENTITY_ALIAS, 
       KEY_PASSWORD); 

     Certificate[] chain = keyStore.getCertificateChain(END_ENTITY_ALIAS); 
     CertStore certsAndCRLs = CertStore.getInstance("Collection", 
       new CollectionCertStoreParameters(Arrays.asList(chain)), "BC"); 
     X509Certificate cert = (X509Certificate) chain[0]; 

     // set up the generator 
     CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); 
     gen.addSigner(key, cert, CMSSignedDataGenerator.DIGEST_SHA224); 
     gen.addCertificatesAndCRLs(certsAndCRLs); 

     // create the signed-data object 
     CMSProcessable data = new CMSProcessableByteArray(plainTextToSign); 
     CMSSignedData signed = gen.generate(data, "BC"); 

     // recreate 
     signed = new CMSSignedData(data, signed.getEncoded()); 
     // ContentInfo conInf = signed.getContentInfo(); 
     // CMSProcessable sigContent = signed.getSignedContent(); 

     new File("D:\\pkcs7\\encrypted-file.p7b"); 
     FileOutputStream fileOuputStream = new FileOutputStream(
       "D:\\pkcs7\\encrypted-file.p7b"); 
     fileOuputStream.write(signed.getEncoded()); 
     // fileOuputStream.flush(); 
     fileOuputStream.close(); 
     return signed; 
    } 

    public static boolean verifyData(KeyStore keyStore) throws Exception { 

     File file = new File("D:\\pkcs7\\encrypted-file.p7b"); 
     FileInputStream fileInputStream = new FileInputStream(file); 
     byte[] signedByte = new byte[(int) file.length()]; 
     fileInputStream.read(signedByte); 
     fileInputStream.close(); 

     // verification step 
     X509Certificate rootCert = (X509Certificate) keyStore 
       .getCertificate(ROOT_ALIAS); 

     CMSSignedData signed = new CMSSignedData(signedByte); 
     if (isValidSignature(signed, rootCert)) { 
      System.out.println("verification succeeded"); 
      return true; 
     } else { 
      System.out.println("verification failed"); 
     } 
     return false; 
    } 

    /** 
    * Take a CMS SignedData message and a trust anchor and determine if the 
    * message is signed with a valid signature from a end entity entity 
    * certificate recognized by the trust anchor rootCert. 
    */ 
    @SuppressWarnings("rawtypes") 
    private static boolean isValidSignature(CMSSignedData signedData, 
      X509Certificate rootCert) throws Exception { 

     boolean[] bArr = new boolean[2]; 
     bArr[0] = true; 
     CertStore certsAndCRLs = signedData.getCertificatesAndCRLs(
       "Collection", "BC"); 
     SignerInformationStore signers = signedData.getSignerInfos(); 
     Iterator it = signers.getSigners().iterator(); 

     if (it.hasNext()) { 
      SignerInformation signer = (SignerInformation) it.next(); 
      SignerId signerConstraints = signer.getSID(); 
      signerConstraints.setKeyUsage(bArr); 
      PKIXCertPathBuilderResult result = buildPath(rootCert, 
        signer.getSID(), certsAndCRLs); 
      return signer.verify(result.getPublicKey(), "BC"); 
     } 

     return false; 
    } 

    /** 
    * Build a path using the given root as the trust anchor, and the passed in 
    * end constraints and certificate store. 
    * <p> 
    * Note: the path is built with revocation checking turned off. 
    */ 
    public static PKIXCertPathBuilderResult buildPath(X509Certificate rootCert, 
      X509CertSelector endConstraints, CertStore certsAndCRLs) 
      throws Exception { 
     CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC"); 
     PKIXBuilderParameters buildParams = new PKIXBuilderParameters(
       Collections.singleton(new TrustAnchor(rootCert, null)), 
       endConstraints); 

     buildParams.addCertStore(certsAndCRLs); 
     buildParams.setRevocationEnabled(false); 

     return (PKIXCertPathBuilderResult) builder.build(buildParams); 
    } 
} 
+0

你應該在文件中寫,或者你應該怎麼寫你的代碼是什麼? – tibtof

+0

我應該如何編寫代碼? –

+0

只是一個問題:就是這個代碼從早期的問題明顯不同?請嘗試和後續/接受您的問題Arvind的答案... –

回答

0

當簽名包裝,你不」不需要向文件寫入任何東西 - 簽名操作的產物是用簽名包裹包裝的數據。請注意,此類簽名數據不能由處理原始未簽名數據的應用程序直接處理。例如。如果您使用包裹PKCS#7/CMS簽名簽署PDF文檔,Adobe公司的閱讀器將無法直接打開簽名的數據(直到簽名被刪除)。通過將簽名數據提供給驗證程序來驗證簽名。

隨着分離的簽名的簽名操作的產品是簽名塊本身,其可以在一個單獨的文件或作爲一些文件系統的替代數據流或在數據庫中的獨立字段存儲。您的原始數據在這種情況下保持不變。通過將原始數據和簽名塊提供給驗證程序來驗證簽名。

+0

我的理解是 假設我的文本是:12345 簽名是:89 所以簽名的數據將變得像#12 $ 34!#!@ 589 now this數據將寫入文件,我們將從文件中讀取這些數據,並驗證我們將刪除此簽名並獲取原始內容。 **如果這是正確的我如何使用充氣城堡** –

+0

@Arvind你的理解是正確的它做的。我不知道如何在BouncyCastle中做到這一點。我們爲Java提供了我們自己的加密解決方案。 –

+0

感謝@Eugene Mayevski「EldoS –