Bouncycastle Signaturen anhängen

Kababär

Top Contributor
Welche Signatur willst du denn verwenden?
Die Datei kannst du entschlüsseln, indem du den eindeutigen Public Key verwendest (denn es geht hier um Integrität).

Edit: Wobei für gewöhnlich nur ein Hashwert signiert (verschlüsselt) wird. Die Datei an sich wird dabei nicht verschlüsselt.
 

Novaa

Mitglied
Danke für die Antworten :)
Ich füge mal meinen Code hinzu damit Ihr es ein bisschen nachvollziehen könnt. Eigentlich möchte ich nur das die Datei signiert wird und dann einen Schreibschutz erhält.
Code:
public class FileSignature {
    static final String KEYSTORE_FILE = "KeyStoreDemo.p12";
    static final String KEYSTORE_INSTANCE = "pkcs12";
    static final String KEYSTORE_PWD = "demo";
    static final String KEYSTORE_ALIAS = "test";

    public void SignatureFile() throws Exception {

        File file = new File("zugferdXmlToDB2.map");
        FileInputStream stream = new FileInputStream(file);
        byte data[] = new byte[(int) file.length()];
        stream.read(data);
     
        Security.addProvider(new BouncyCastleProvider());
        KeyStore ks = KeyStore.getInstance(KEYSTORE_INSTANCE);

        ks.load(new FileInputStream(KEYSTORE_FILE), KEYSTORE_PWD.toCharArray());

        Key key = ks.getKey(KEYSTORE_ALIAS, KEYSTORE_PWD.toCharArray());

        if ( key instanceof PrivateKey ) {
            // Build CMS
            Certificate cert = ks.getCertificate(KEYSTORE_ALIAS);

            DSAPrivateKey keyPriv = (DSAPrivateKey) key;
            DSAPublicKey keyPub = (DSAPublicKey) cert.getPublicKey();

            byte[] digitalSignature = signData(data, keyPriv);

            boolean verified;

            verified = verifySig(data, keyPub, digitalSignature);

            if ( verified ){
                writeSignedFile(digitalSignature, file);
            }
        }
     
    }

    public static byte[] signData(byte[] data, PrivateKey Key) throws Exception {

        Signature signer = Signature.getInstance("SHA1withDSA");
        signer.initSign(Key);
        signer.update(data);
        return ( signer.sign() );
    }

    public static boolean verifySig(byte[] data, PublicKey Key, byte[] sig) throws Exception {
        Signature signer = Signature.getInstance("SHA1withDSA");
        signer.initVerify(Key);
        signer.update(data);
        return ( signer.verify(sig) );
    }

    private void writeSignedFile(byte[] digitalSignature, File file) throws IOException {
        FileOutputStream output = new FileOutputStream("test/" + file);
        output.write(digitalSignature);
        output.close();
    }

}

Als Export erhalte ich das 0,>ÌÔæ.ý+À\O ©®˜ÖùjuH°ª¦<©»òÓº g@³÷«
 

Kababär

Top Contributor
Als Export wohin? Und womit öffnest du es? Daten sind alle nur bytes. Es obliegt den Programmen wie diese zu interpretieren sind. Deshalb kann es sein, dass es auf den ersten Moment nicht verschlüsselt oder einfach falsch wirkt.
Normalerweise erstellst du einen Hash und signierst diesen, nicht die ganze Datei.
Und Schreibschutz erhälst du dadurch nicht. Eher um Datenschutz im weiteren Sinne, also Integrität.
 

Novaa

Mitglied
Erstmal zu deinen Fragen die Datei soll in das Alte Datei Format die Datei öffne ich mit notepad++. Wie bekomme ich das den hin nur einen Hash zu signieren und diesen dann der Datei hinzuzufügen ?
 

Novaa

Mitglied
Erstmal zu deinen Fragen die Datei soll in das Alte Datei Format die Datei öffne ich mit notepad++. Wie bekomme ich das den hin nur einen Hash zu signieren und diesen dann der Datei hinzuzufügen ?
Als Export wohin? Und womit öffnest du es? Daten sind alle nur bytes. Es obliegt den Programmen wie diese zu interpretieren sind. Deshalb kann es sein, dass es auf den ersten Moment nicht verschlüsselt oder einfach falsch wirkt.
Normalerweise erstellst du einen Hash und signierst diesen, nicht die ganze Datei.
Und Schreibschutz erhälst du dadurch nicht. Eher um Datenschutz im weiteren Sinne, also Integrität.

Sry für die umständliche Schreibweise
  • Datei wird anschließend im .map Format gespeichert (xml)
  • Die Datei öffne ich momentan mit Notepad++
  • Datei soll am Ende nur Lesbar gemacht werden
  • Signatur soll in einer .p7s Datei stehen und die Signierten Daten liegen in einer anderen Datei
Wie müsste ich das Programm abändern damit das richtig funtioniert ? Wenn ich die Byte Daten mit .hashcode abrufe geht das nicht. Da die .update Methode von Signature nur Byte [] zulässt. Gibt es eine Funktion von Bouncycastle die das kann?

Ich hoffe ihr könnt mir weiterhelfen :)
 
Zuletzt bearbeitet:

Kababär

Top Contributor
Wieso BouncyCastle? Bist du an diese Bib gebunden?

Für das Erstellen einer Signatur gibt es mehrere Verfahren. Ich denke du solltest dir erstmal klar darüber werden, welches Verfahren du verwenden willst.

Und nochmal: signieren ist nicht das gleiche wie verschlüsseln!
Wenn du verschlüsseln willst, guck dir Chiphre, AES, RSA, etc an.
 

Novaa

Mitglied
Wieso BouncyCastle? Bist du an diese Bib gebunden?

Für das Erstellen einer Signatur gibt es mehrere Verfahren. Ich denke du solltest dir erstmal klar darüber werden, welches Verfahren du verwenden willst.

Und nochmal: signieren ist nicht das gleiche wie verschlüsseln!
Wenn du verschlüsseln willst, guck dir Chiphre, AES, RSA, etc an.
Es soll nichts verschlüsselt werden. Es soll einfach der Inhalt signiert werden und die Signatur in eine p7s Datei exportiert werden.
Könntest du mir sagen wie ich das hinbekomme
 
Zuletzt bearbeitet:

Kababär

Top Contributor
Ah, jetzt hab ich auch mal verstanden was du eigentlich willst.

Hmmm ne direkte Lösung gebe ich dir nicht, aber mal einen Link zum Lesen:
https://docs.oracle.com/javase/tutorial/security/apisign/step3.html

Über Google findet man doch dutzende Ergebisse. Die extension einer Datei ist nur eine extension und Daten sind nur Bytes. Einfach heißt das: die Signatur einfach in die Datei schreiben.

Edit: Da ich aber denke, dass aus meiner Antwort kein Schuh wird, gebe ich dir mal einen Link, der dir auch so noch bisschen was erklärt (hab das Gefühl du bist mit der Theorie noch nicht so ganz vertraut), denn das ist mir jetzt zu viel zum Schreiben und ich denke das tuts einfach:
https://www.google.de/amp/s/mydevel...how-to-generate-pkcs7-signatures-in-java/amp/
Falls du dann noch Fragen hast, kannst du gerne Fragen :)
 

Kababär

Top Contributor
Wieso sollte ich verschlüsselte Daten signieren ... ist doch viel zu lang und aufwendig.
Mach dich mal schlau über
pkcs
cms

Insbesondere p7s ist der pkcs#7 und der kann zum Signieren und/oder Verschlüsseln benutzt werden. Das heißt in der Datei können Daten und die Signatur stehen.
Belegst du gerade das Fach oder interessiert dich das?
Wozu brauchst du das eigentlich?
 

Kababär

Top Contributor
Oracle hat dazu sehr ausführliche Informationen auf der Seite, die ich dir gegeben habe.
https://docs.oracle.com/javase/tutorial/security/apisign/vstep4.html
Direkter Link falls du es nicht findest...

Falls du es mit BouncyCastle gemacht hast, gibt es zwei Wege:
1. mit den gekapselten Daten
Code:
CMSSignedData signedData = new CMSSignedData(Base64.decode(sig.getBytes()));
Wobei sig hier dein Signatur-Objekt ist

2.
Code:
CMSProcessable signedContent = new CMSProcessableByteArray(content.getBytes("ISO-8859-1"));
InputStream is = new ByteArrayInputStream(Base64.decode(sig.getBytes()));
CMSSignedData signedData = new CMSSignedData(signedContent, is);
Falls du keine gekapselten Daten hast sondern nur die Signatur an sich.

Dann kann es ganz normal weitergehen, bspw. so:
Code:
Store store = signedData.getCertificates();
SignerInformationStore signerInfo = signedData.getSignerInfos();

Collection coll = signerInfo.getSigners();
Iterator it = coll.iterator();

while (it.hasNext()) {
    SignerInformation signer = (SignerInformation)it.next();

    Collection certCollection = store.getMatches(signer.getSID());
    Iterator certIt = certCollection.iterator();

    X509CertificateHolder certHolder = (X509CertificateHolder)certIt.next();
    X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);

    //Prüfen, ob Signatur gültig ist
    if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))) {
        //To-Do
    }
}

Hoffe ich konnte weiterhelfen.
 

Ähnliche Java Themen

Neue Themen


Oben