2016-04-13 19 views
0

Ich muss eine Datei signieren und bisher habe ich die openssl Comman verwendet, die gut funktioniert (Datei ist signiert und verifiziert).Replizieren OpenSSL Befehl zum Signieren einer Datei in Java

Aber jetzt muss ich dies zur Laufzeit tun, also muss ich die Datei programmgesteuert signieren. Ich verwende BouncyCastle, aber ich bin offen, um zu einer anderen Bibliothek zu wechseln.

Ich bin nicht qualifiziert mit Zertifikaten und noch weniger mit BouncyCastle. Das ist, womit ich gekommen bin.

Die entsprechenden Dateien aus dem OpenSSL-Befehl an den Code unten sind:

myCrtFile.crt -> signerCertHolder 
myKeyFile.key -> privateKeyInfo 
bundleCertificate.crt -> certificateHolder 

public byte[] sign(String message) throws IOException, CMSException, OperatorCreationException, CertificateEncodingException, MessagingException, CertificateException { 
    Security.addProvider(new BouncyCastleProvider()); 

    PrivateKeyInfo privateKeyInfo = loadInKey(); 
    X509CertificateHolder signerCertHolder = loadSigner(); 
    X509CertificateHolder certificateCertHolder = loadCertfile(); 

    PrivateKey inKey = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo); 

    JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter(); 
    X509Certificate signer = certificateConverter.getCertificate(signerCertHolder); 
    X509Certificate certificate = certificateConverter.getCertificate(certificateCertHolder); 

    List<X509Certificate> certificateList = new ArrayList(); 
    certificateList.add(signer); 
    certificateList.add(certificate); 

    Store<?> certs = new JcaCertStore(certificateList); 
    ContentSigner sha1signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(inKey); 
    JcaSignerInfoGeneratorBuilder jcaSignerInfoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()); 

    CMSSignedDataGenerator signGen = new CMSSignedDataGenerator(); 
    signGen.addSignerInfoGenerator(jcaSignerInfoGeneratorBuilder.build(sha1signer, certificate)); 
    signGen.addCertificates(certs); 

    CMSTypedData content = new CMSProcessableByteArray(message.getBytes()); 
    CMSSignedData signedData = signGen.generate(content, false); 
    byte[] signeddata = signedData.getEncoded(); 

    return signeddata; 
} 

Dann speichere ich die byte[] in eine Datei. Wenn ich die Datei öffne (es ist eine MDM mobileConfig-Datei), heißt es "Die Datei ist signiert, konnte aber nicht verifiziert werden". Ich fühle, dass ich der Lösung nahe bin, aber ich weiß nicht, was ich falsch mache.

Kann mir jemand helfen, herauszufinden, was ich vermisse, um die Datei verifizieren zu lassen?

PS; Die Zertifikate stammen aus einem SSL-Zertifikat (GoDaddy) und das bundleCertificate.crt ist das GoDaddy-Paketzertifikat.

Antwort

1

Ich habe es geschafft, die Datei zu signieren. Wie vermutet, war ich der endgültigen Lösung nahe. Hier ist der vollständige Code.

public byte[] signMobileConfig(byte[] mobileconfig) 
     throws CertificateEncodingException, PEMException, FileNotFoundException, IOException, CertificateException, OperatorCreationException, CMSException { 
    Security.addProvider(new BouncyCastleProvider()); 

    X509CertificateHolder caCertificate = loadCertfile(); 

    JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter(); 
    X509Certificate serverCertificate = certificateConverter.getCertificate(loadSigner()); 

    PrivateKeyInfo privateKeyInfo = loadInKey(); 
    PrivateKey inKey = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo); 
    ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(inKey); 

    CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); 
    JcaDigestCalculatorProviderBuilder digestProviderBuilder = new JcaDigestCalculatorProviderBuilder().setProvider("BC"); 
    JcaSignerInfoGeneratorBuilder generatotBuilder = new JcaSignerInfoGeneratorBuilder(digestProviderBuilder.build()); 

    generator.addSignerInfoGenerator(generatotBuilder.build(sha1Signer, serverCertificate)); 
    generator.addCertificate(new X509CertificateHolder(serverCertificate.getEncoded())); 
    generator.addCertificate(new X509CertificateHolder(caCertificate.getEncoded())); 

    CMSProcessableByteArray bytes = new CMSProcessableByteArray(mobileconfig); 
    CMSSignedData signedData = generator.generate(bytes, true); 

    return signedData.getEncoded(); 
} 

Und hier ist, wie ich die Dateien laden:

public X509CertificateHolder loadSigner() throws FileNotFoundException, IOException { 
    InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.crt"); 
    PEMParser parser = new PEMParser(new InputStreamReader(inputStream)); 
    return (X509CertificateHolder) parser.readObject(); 
} 

public PrivateKeyInfo loadInKey() throws FileNotFoundException, IOException { 
    InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.key"); 
    PEMParser parser = new PEMParser(new InputStreamReader(inputStream)); 
    return (PrivateKeyInfo) parser.readObject(); 
} 

public X509CertificateHolder loadCertfile() throws FileNotFoundException, IOException { 
    InputStream inputStream = externalResourcesFacade.getResourceAsStream("path/to/.crt"); 
    PEMParser parser = new PEMParser(new InputStreamReader(inputStream)); 
    return (X509CertificateHolder) parser.readObject(); 
}