- Verschlüsselung, PKCS#7
Ich bin mit Hüpfburg zur Verfügung gestellt Bibliothek zu verschlüsseln,entschlüsseln,signieren und überprüfen von Zeichen.
Ich Tue dies als
1. Verschlüsseln von Daten
2. Signieren der Daten
3. Schreiben vorzeichenbehaftetes byte in einer Datei
4. Lesen signed byte aus der Datei
5. Signatur überprüfen
6. Entschlüsseln von Daten
Habe ich Bezug genommen, von Anfang Kryptographie mit Java
Mein problem ist, in Schritt 5, wenn ich bin der überprüfung von Daten, ich bin immer
org.bouncycastle.cms.CMSException: message-digest Attribut-Wert hat
nicht mit berechneter Wert
Mein code ist unten
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertStore;
import java.security.cert.Certificate;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import javax.security.auth.x500.X500Principal;
import javax.security.auth.x500.X500PrivateCredential;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
import org.bouncycastle.cms.CMSEnvelopedDataParser;
import org.bouncycastle.cms.CMSProcessable;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.RecipientId;
import org.bouncycastle.cms.RecipientInformation;
import org.bouncycastle.cms.RecipientInformationStore;
import org.bouncycastle.cms.SignerId;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.x509.X509V1CertificateGenerator;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
public class Test {
private static final char[] KEY_STORE_PASSWORD = "123456".toCharArray();
private static final long VALIDITY_PERIOD = 365 * 24 * 60 * 60 * 1000;
private static final char[] KEY_PASSWORD = "keyPassword".toCharArray();
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";
public static void main(String[] args) {
try{
//CREATE KEY STORE
KeyStore keyStore = createKeyStore();
//STEP 1. ENCRYPT AND SIGN
byte[] step1Data = encryptData(keyStore, PLAIN_TEXT.getBytes());
CMSSignedData cmsSignedData = signData(keyStore,step1Data);
new File("D:\\pkcs7\\encrypted-file.p7b");
FileOutputStream fileOuputStream = new FileOutputStream("D:\\pkcs7\\encrypted-file.p7b");
fileOuputStream.write(cmsSignedData.getEncoded());
fileOuputStream.flush();
fileOuputStream.close();
//STEP 2. READ ENCRYPTED DATA AND VERIFY SIGN AND DECRYPT IT
File file =new File("D:\\pkcs7\\encrypted-file.p7b");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] encryptedAndSignedByte = new byte[(int)file.length()];
fileInputStream.read(encryptedAndSignedByte );
fileInputStream.close();
cmsSignedData = new CMSSignedData(encryptedAndSignedByte);
if( verifyData(keyStore, cmsSignedData) == true ){
decryptData(keyStore,encryptedAndSignedByte);
}
}catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* This method will encrypt data
*/
private static byte[] encryptData(KeyStore keyStore, byte[] plainData) throws Exception {
PrivateKey key = (PrivateKey) keyStore.getKey(END_ENTITY_ALIAS,
KEY_PASSWORD);
Certificate[] chain = keyStore.getCertificateChain(END_ENTITY_ALIAS);
X509Certificate cert = (X509Certificate) chain[0];
//set up the generator
CMSEnvelopedDataGenerator gen = new CMSEnvelopedDataGenerator();
gen.addKeyTransRecipient(cert);
//create the enveloped-data object
CMSProcessable data = new CMSProcessableByteArray(plainData);
CMSEnvelopedData enveloped = gen.generate(data,
CMSEnvelopedDataGenerator.AES128_CBC, "BC");
return enveloped.getEncoded();
//recreate
}
private static byte[] decryptData(KeyStore keyStore,byte[] encryptedData) throws Exception{
CMSEnvelopedDataParser envelopedDataParser = new CMSEnvelopedDataParser(new ByteArrayInputStream(encryptedData));
PrivateKey key = (PrivateKey) keyStore.getKey(END_ENTITY_ALIAS,KEY_PASSWORD);
Certificate[] chain = keyStore.getCertificateChain(END_ENTITY_ALIAS);
X509Certificate cert = (X509Certificate) chain[0];
CMSEnvelopedData enveloped = new CMSEnvelopedData(encryptedData);
//look for our recipient identifier
RecipientId recId = new RecipientId();
recId.setSerialNumber(cert.getSerialNumber());
recId.setIssuer(cert.getIssuerX500Principal().getEncoded());
RecipientInformationStore recipients = enveloped.getRecipientInfos();
RecipientInformation recipient = recipients.get(recId);
if (recipient != null) {
//decrypt the data
byte[] recData = recipient.getContent(key, "BC");
System.out.println("----------------------- RECOVERED DATA -----------------------");
System.out.println(new String(recData));
System.out.println("--------------------------------------------------------------");
return recData;
} else {
System.out.println("could not find a matching recipient");
}
return null;
}
private static CMSSignedData signData(KeyStore keyStore,byte[] encryptedData ) 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(encryptedData);
CMSSignedData signed = gen.generate(data, "BC");
//recreate
signed = new CMSSignedData(data, signed.getEncoded());
//ContentInfo conInf = signed.getContentInfo();
//CMSProcessable sigContent = signed.getSignedContent();
return signed;
}
private static boolean verifyData(KeyStore keyStore, CMSSignedData signed)
throws Exception {
//verification step
X509Certificate rootCert = (X509Certificate) keyStore.getCertificate(ROOT_ALIAS);
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.
*/
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);
}
/**
* Create a KeyStore containing the a private credential with certificate
* chain and a trust anchor.
*/
public static KeyStore createKeyStore() throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);
keyStore.load(null, null);
X500PrivateCredential rootCredential = createRootCredential();
X500PrivateCredential interCredential = createIntermediateCredential(
rootCredential.getPrivateKey(), rootCredential.getCertificate());
X500PrivateCredential endCredential = createEndEntityCredential(
interCredential.getPrivateKey(),
interCredential.getCertificate());
keyStore.setCertificateEntry(rootCredential.getAlias(),
rootCredential.getCertificate());
keyStore.setKeyEntry(
endCredential.getAlias(),
endCredential.getPrivateKey(),
KEY_PASSWORD,
new Certificate[] { endCredential.getCertificate(),
interCredential.getCertificate(),
rootCredential.getCertificate() });
keyStore.store(new FileOutputStream("d:\\pkcs7\\KeyStore.jks"),
KEY_STORE_PASSWORD);
return keyStore;
}
/**
* Create a random 1024 bit RSA key pair
*/
public static KeyPair generateRSAKeyPair() throws Exception {
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC");
kpGen.initialize(1024, new SecureRandom());
return kpGen.generateKeyPair();
}
/**
* Generate a sample V1 certificate to use as a CA root certificate
*/
public static X509Certificate generateCertificate(KeyPair pair)
throws Exception {
X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
certGen.setSerialNumber(BigInteger.valueOf(1));
certGen.setIssuerDN(new X500Principal("CN=Test CA Certificate"));
certGen.setNotBefore(new Date(System.currentTimeMillis()
- VALIDITY_PERIOD));
certGen.setNotAfter(new Date(System.currentTimeMillis()
+ VALIDITY_PERIOD));
certGen.setSubjectDN(new X500Principal("CN=Test CA Certificate"));
certGen.setPublicKey(pair.getPublic());
certGen.setSignatureAlgorithm("SHA1WithRSAEncryption");
return certGen.generateX509Certificate(pair.getPrivate(), "BC");
}
/**
* Generate a sample V1 certificate to use as a CA root certificate
*/
public static X509Certificate generateRootCert(KeyPair pair)
throws Exception {
X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
certGen.setSerialNumber(BigInteger.valueOf(1));
certGen.setIssuerDN(new X500Principal("CN=Test CA Certificate"));
certGen.setNotBefore(new Date(System.currentTimeMillis()
- VALIDITY_PERIOD));
certGen.setNotAfter(new Date(System.currentTimeMillis()
+ VALIDITY_PERIOD));
certGen.setSubjectDN(new X500Principal("CN=Test CA Certificate"));
certGen.setPublicKey(pair.getPublic());
certGen.setSignatureAlgorithm("SHA1WithRSAEncryption");
return certGen.generateX509Certificate(pair.getPrivate(), "BC");
}
/**
* Generate a sample V3 certificate to use as an end entity certificate
*/
public static X509Certificate generateEndEntityCert(PublicKey entityKey,
PrivateKey caKey, X509Certificate caCert) throws Exception {
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
certGen.setSerialNumber(BigInteger.valueOf(1));
certGen.setIssuerDN(caCert.getSubjectX500Principal());
certGen.setNotBefore(new Date(System.currentTimeMillis()
- VALIDITY_PERIOD));
certGen.setNotAfter(new Date(System.currentTimeMillis()
+ VALIDITY_PERIOD));
certGen.setSubjectDN(new X500Principal("CN=Test End Certificate"));
certGen.setPublicKey(entityKey);
certGen.setSignatureAlgorithm("SHA1WithRSAEncryption");
certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
new AuthorityKeyIdentifierStructure(caCert));
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
new SubjectKeyIdentifierStructure(entityKey));
certGen.addExtension(X509Extensions.BasicConstraints, true,
new BasicConstraints(false));
certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(
KeyUsage.digitalSignature | KeyUsage.keyEncipherment));
return certGen.generateX509Certificate(caKey, "BC");
}
/**
* Generate a X500PrivateCredential for the root entity.
*/
public static X500PrivateCredential createRootCredential() throws Exception {
KeyPair rootPair = generateRSAKeyPair();
X509Certificate rootCert = generateRootCert(rootPair);
return new X500PrivateCredential(rootCert, rootPair.getPrivate(),
ROOT_ALIAS);
}
/**
* Generate a X500PrivateCredential for the intermediate entity.
*/
public static X500PrivateCredential createIntermediateCredential(
PrivateKey caKey, X509Certificate caCert) throws Exception {
KeyPair interPair = generateRSAKeyPair();
X509Certificate interCert = generateIntermediateCert(
interPair.getPublic(), caKey, caCert);
return new X500PrivateCredential(interCert, interPair.getPrivate(),
INTERMEDIATE_ALIAS);
}
/**
* Generate a X500PrivateCredential for the end entity.
*/
public static X500PrivateCredential createEndEntityCredential(
PrivateKey caKey, X509Certificate caCert) throws Exception {
KeyPair endPair = generateRSAKeyPair();
X509Certificate endCert = generateEndEntityCert(endPair.getPublic(),
caKey, caCert);
return new X500PrivateCredential(endCert, endPair.getPrivate(),
END_ENTITY_ALIAS);
}
/**
* Generate a sample V3 certificate to use as an intermediate CA certificate
*/
public static X509Certificate generateIntermediateCert(PublicKey intKey,
PrivateKey caKey, X509Certificate caCert) throws Exception {
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
certGen.setSerialNumber(BigInteger.valueOf(1));
certGen.setIssuerDN(caCert.getSubjectX500Principal());
certGen.setNotBefore(new Date(System.currentTimeMillis()));
certGen.setNotAfter(new Date(System.currentTimeMillis()
+ VALIDITY_PERIOD));
certGen.setSubjectDN(new X500Principal(
"CN=Test Intermediate Certificate"));
certGen.setPublicKey(intKey);
certGen.setSignatureAlgorithm("SHA1WithRSAEncryption");
certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
new AuthorityKeyIdentifierStructure(caCert));
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
new SubjectKeyIdentifierStructure(intKey));
certGen.addExtension(X509Extensions.BasicConstraints, true,
new BasicConstraints(0));
certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(
KeyUsage.digitalSignature | KeyUsage.keyCertSign
| KeyUsage.cRLSign));
return certGen.generateX509Certificate(caKey, "BC");
}
}
- Im Zusammenhang frühere Frage durch den gleichen Benutzer
- Ihre Frage scheint konzentriert sich auf
.p7b
- Dateien. Aber Datei-Erweiterungen sind lediglich Konventionen. Es wäre besser, wenn könnten Sie konzentrieren sich auf die Programmierung problem, das Sie lösen möchten und wo Sie stecken in die Verfolgung. Auf diese Weise könnten wir besser helfen. Das sagte ich Ihnen eine Antwort zu Fragen, aber ich bezweifle es wird Euch näher an die Lösung Ihres Problems. - nur ein Hinweis auf der Bestellung zwischen Verschlüsselung und Signatur. Bitte, werden Sie sicher zuerst signieren und dann verschlüsseln (im Gegensatz zu dem, was du geschrieben hast in deinem post). Ansonsten Ihnen vorliegt viele Fragen. Zum Beispiel, die Identität des Emittenten ist durchgesickert und auch jemand entfernen konnte, die Signatur, und fügen Sie Ihre eigenen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
In der typischen Anwendung einer
.p7b
- Datei enthält nur den öffentlichen Schlüssel, Zertifikate und nie einen privaten Schlüssel. Es wird oft verwendet, um das speichern einer ganzen Kette von Zertifikaten, anstatt einem einzigen Zertifikat. Die 'p7b' name kommt von dem format, welches auch in der degenerierten form des PKCS#7-SignedData-Struktur. In der Regel, die privaten Schlüssel gespeichert sind, in einer PKCS#12 (oft eine Datei, die entweder ein.p12
oder eine.pfx
Erweiterung) Datei, aber andere Formate sind ebenfalls üblich.Lesen in die Zertifikate von einem p7b-Datei, die Sie verwenden können, die CertificateFactory Klasse. Eine PKCS#12-Datei direkt verwendbar ist als keystore.
Die Sie erwähnen, PKCS#7 Häufig. PKCS#7 ist ein Alter standard, ist sehr groß und offen. In diesen Tagen der standard, dass ist mehr allgemein implementiert eine erweiterte Teilmenge der PKCS#7-CMS genannt. Es ist ein IETF-standard, dokumentiert im RFC 5652. Die Bouncycastle PKIX/CMS-Bibliothek bietet eine umfassende Unterstützung für die CMS-Spezifikation.