2017-05-12 6 views
2

Ich möchte eine Datei signieren, die ich mit JFileChooser eingelesen habe. Aber wenn ich es auf das Terminal drucke, kann ich nur Questmarks und andere nicht lesbare Zeichen lesen. Mein Code zu unterzeichnen ist:Konvertieren Sie die Unterschrift in lesbar (Bouncycastle)

public static void sign() throws Exception{ 
    byte[] file = fileChooser(); 

    store = KeyStore.getInstance(storeType); 
    FileInputStream in = new FileInputStream(new File(storePath)); 
    store.load(in, storePassword); 
    in.close(); 

    Key priv = store.getKey("test", storePassword); 
    System.out.println(priv.toString() + "priv string"); 
    X509Certificate cert = (X509Certificate) store.getCertificate("Subject"); 
    ContentSigner signer = new JcaContentSignerBuilder("SHA512withRSA").build((RSAPrivateKey) priv);   

    //Sign Data 
    Signature signature = Signature.getInstance("SHA512WithRSA"); 
    signature.initSign((RSAPrivateKey) priv); 
    signature.update(file); 

    //Build cms 
    CMSTypedData data = new CMSProcessableByteArray(signature.sign()); 
    CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); 

    gen.addSignerInfoGenerator(
      new JcaSignerInfoGeneratorBuilder(
        new JcaDigestCalculatorProviderBuilder().build()) 
        .build(signer, cert)); 

    //Get signed data 
    CMSSignedData sigData = gen.generate(data, false); 

    byte[] sig = (byte[]) sigData.getSignedContent().getContent(); 
    sig.toString(); 
    String content = new String(sig); 
    System.out.println("Signed content: " + content + "\n"); 
} 

Wie kann ich die Signatur Menschen lesbares Format? erwarten

Antwort

2

Die digitale Signatur ist ein Array von Bytes, die nicht in einem für Menschen lesbaren Format vorliegen, so ein String mit ihm zu schaffen, wie Sie nicht.

Wenn Sie ein „lesbar“ Format haben möchten, können Sie es zu Base64 kodieren, BouncyCastle die mit org.bouncycastle.util.encoders.Base64 Klasse (ich verwende BouncyCastle 1,56, aber frühere Versionen könnten ähnliche Klassen für Base64 Umwandlung haben):

byte[] base64ByteArray = Base64.encode(sig); // sig is your byte array 
String humanReadableString = new String(base64ByteArray); // human readable string 

Um die ursprüngliche sig Array zurück, können Sie die humanReadableString dekodieren muss:

byte[] originalSigBytes = Base64.decode(humanReadableString.getBytes()); 
// originalSigBytes will be the same as sig 

Hinweise: Wenn Sie ein Problem im Zusammenhang mit Codierung stellen, können Sie die Codierung mit der java.nio.charset.Charset Klasse erzwingen (in diesem Beispiel verwende ich UTF-8 aber Sie können, was kodiert Ihr System verwenden verwendet):

// same thing as above, but using a specific encoding (UTF-8 in this case) 
String humanReadableString = new String(base64ByteArray, Charset.forName("UTF-8")); 
byte[] originalSigBytes = Base64.decode(humanReadableString.getBytes(Charset.forName("UTF-8"))); 

Alternative

Wenn Sie möchten, können Sie auch zu einem Hex-encoded string (jedes Byte wird eine String-Darstellung seines Wertes in der Basis 16) umwandeln, BouncyCastle der org.bouncycastle.util.encoders.Hex-Klasse:

byte[] hexEncodedArray = Hex.encode(sig); 
String humanReadableString = new String(hexEncodedArray, Charset.forName("UTF-8")); 

Und Ihren ursprünglichen sig Array zurück:

byte[] originalSigBytes = Hex.decode(humanReadableString.getBytes(Charset.forName("UTF-8"))); 
// originalSigBytes will be the same as sig 

Eine weitere Sache:, wenn sie mit Kryptographie Sachen zu tun, empfehle ich Sie immer die byte Array zu manipulieren, anstatt sie zu String der Umwandlung . Wenn jedoch die Konvertierung in String obligatorisch ist, verwenden Sie Base64 (oder Hex-codierte Zeichenfolge).

+0

Bei beiden Codierungsmethoden gibt es mir den Fehler: Die Methode encode (byte []) im Typ Hex ist nicht anwendbar für die Argumente (CMSSignedData) – nolags

+1

Sie müssen die Variable 'byte [] sig' verwenden, nicht die' ' sigData' –

Verwandte Themen