2012-06-22 75 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 –