私の Java アプレットは、切り離されたタイプの Bouncy Castle 1.4.9 を使用して CMSSignedData を生成できます。次に、バイト配列 sigData.getEncoded() がサーバー上のテーブルに格納されます (このサーバーは、含まれていないコンテンツ データにアクセスできます)。ここで、ユーザーが .p7m ファイルをダウンロードできるように、エンベロープされた CMSSignedData をサーバーに作成したいと思います。
私が開発する必要がある関数には、切り離された署名のバイト配列とコンテンツ データのバイト配列があり、.p7m ファイルのダウンロードに使用される CaDES エンベロープ署名のバイト配列を返す必要があります。
問題は、切り離された署名者を封筒付きの署名者に変換できなかったことです。
アプレットで使用したコードを 次に示します。signCAdeSは分離署名を使用してドキュメントに署名し、 (テストのためだけに) attachを呼び出して分離署名をエンベロープに変換しますが、成功しませんでした: 作成された .p7m ファイルを Dike で開くことはできませんコンテンツデータを表示します。
private byte[] signCAdES(byte[] aDocument, PrivateKey aPrivateKey, Certificate[] certChain)
throws GeneralSecurityException {
byte[] digitalSignature = null;
try {
Security.addProvider(new BouncyCastleProvider());
ArrayList<X509Certificate> certsin = new ArrayList<X509Certificate>();
for (int i = 0; i < certChain.length; i++) {
certsin.add((X509Certificate) certChain[i]);
}
X509Certificate cert = certsin.get(0);
//Nel nuovo standard di firma digitale e' richiesto l'hash del certificato di sottoscrizione:
String digestAlgorithm = "SHA-256";
String digitalSignatureAlgorithmName = "SHA256withRSA";
MessageDigest sha = MessageDigest.getInstance(digestAlgorithm);
byte[] digestedCert = sha.digest(cert.getEncoded());
//Viene ora create l'attributo ESSCertID versione 2 cosi come richiesto nel nuovo standard:
AlgorithmIdentifier aiSha256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256);
ESSCertIDv2 essCert1 = new ESSCertIDv2(aiSha256, digestedCert);
ESSCertIDv2[] essCert1Arr = {essCert1};
SigningCertificateV2 scv2 = new SigningCertificateV2(essCert1Arr);
Attribute certHAttribute = new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new DERSet(scv2));
//Aggiungiamo l'attributo al vettore degli attributi da firmare:
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(certHAttribute);
AttributeTable at = new AttributeTable(v);
CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator(at);
//Creaiamo l'oggetto che firma e crea l'involucro attraverso le librerie di Bouncy Castle:
SignerInfoGeneratorBuilder genBuild = new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider());
genBuild.setSignedAttributeGenerator(attrGen);
//Si effettua la firma con l'algoritmo SHA256withRSA che crea l'hash e lo firma con l'algoritmo RSA:
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner shaSigner = new JcaContentSignerBuilder("SHA256withRSA").build(aPrivateKey);
SignerInfoGenerator sifGen = genBuild.build(shaSigner, new X509CertificateHolder(cert.getEncoded()));
gen.addSignerInfoGenerator(sifGen);
X509CollectionStoreParameters x509CollectionStoreParameters = new X509CollectionStoreParameters(certsin);
JcaCertStore jcaCertStore = new JcaCertStore(certsin);
gen.addCertificates(jcaCertStore);
CMSTypedData msg = new CMSProcessableByteArray(aDocument);
CMSSignedData sigData = gen.generate(msg, false); // false=detached
byte[] encoded = sigData.getEncoded();
FileOutputStream fos = new FileOutputStream("H:\\prova2.txt.p7m");
fos.write(attach(aDocument, encoded));
fos.flush();
fos.close();
digitalSignature = encoded;
} catch (CMSException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} catch (OperatorCreationException ex) {
ex.printStackTrace();
}
return digitalSignature;
}
アタッチ機能は次のとおりです。
public static byte[] attach(byte[] originalData, byte[] detached) {
try {
ASN1InputStream in = new ASN1InputStream(detached);
CMSSignedData sigData = new CMSSignedData(new CMSProcessableByteArray(originalData), in);
return sigData.getEncoded();
} catch (Exception e) {
return null;
}
}