2017-05-12 7 views
2

私はJFileChooserで読み込んだファイルに署名したいと思います。しかし、私はそれをターミナルに印刷するときには、クオンマークと人間が読めない他の文字だけを読むことができます。 署名する私のコードは次のとおりです。署名を人間が読める形式に変換する(バウンシーキャスル)

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"); 
} 

どのように私は、人間が読めるへの署名をフォーマットすることができますか?

答えて

2

デジタル署名は人間が判読できない形式のバイトの配列なので、Stringを作成すると期待どおりに動作しません。

あなたが「読める」形式を持っているしたい場合、あなたははBouncyCastleのorg.bouncycastle.util.encoders.Base64クラス(私ははBouncyCastle 1.56を使用していますが、以前のバージョンがBase64で変換のための同様のクラスを持っているかもしれません)を使用して、Base64でそれをエンコードすることができます。

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

sig配列を取得するために、あなたはhumanReadableStringをデコードする必要があります。

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

の注意:あなたはエンコーディングに関連するすべての問題に直面した場合、あなたはjava.nio.charset.Charsetクラスとエンコーディングを強制することができます(この例では、私はUTF-8を使用していますが、あなたのシステムが使用するものは何でもエンコードを使用することができます):

// 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"))); 

代替

ご希望の場合は、さらにはBouncyCastleのorg.bouncycastle.util.encoders.Hexクラスを使用して、(各バイトは、ベース16で、その値の文字列表現になります)Hex-encoded stringに変換することができます:

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

とバックあなたの元sig配列を取得します

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

もう一つ:暗号のものを扱う、私はあなたが常に代わりStringに変換するのbyte配列を操作することをお勧め。しかし、Stringに変換する必要がある場合は、Base64(または16進数でエンコードされた文字列)を使用します。

+0

どちらのエンコーディング方法でも、エラー:型Hexのメソッドencode(byte [])は引数(CMSSignedData)には適用されません。 – nolags

+1

'byte [] sig'変数を使用する必要があります。 sigData' –

関連する問題