java - 将签名转换为人类可读 (bouncycaSTLe)

标签 java format bouncycastle signature sign

我想签署一个我用 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");
}

如何将签名格式化为人类可读?

最佳答案

数字签名是一组非人类可读格式的字节,因此使用它创建 String 不会如您预期的那样工作。

如果你想要一个“可读”的格式,你可以使用 BouncyCaSTLe 的 org.bouncycaSTLe.util.encoders.Base64 类(我使用的是 BouncyCaSTLe 1.56,但之前的版本可能具有类似的 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 类强制编码(在这个例子中,我' m 使用 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")));

备选

如果您愿意,还可以转换为 Hex-encoded string (每个字节都以 16 进制表示其值的字符串表示形式),使用 BouncyCaSTLe 的 org.bouncycaSTLe.util.encoders.Hex 类:

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

还有一件事:在处理密码学问题时,我建议您始终操作byte 数组,而不是将它们转换为String。但是,如果必须转换为 String,则使用 Base64(或十六进制编码的字符串)。

关于java - 将签名转换为人类可读 (bouncycaSTLe),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43933298/

相关文章:

C - 读取未知格式的输入

java - 使用 BouncyCaSTLe 轻量级 API 的 AES-256 加密

c# - 签名和创建 asn1 签名消息 - BouncycaSTLe

java - 数组越界异常,找不到问题所在

C fscanf 复杂格式

vim - 使用 VIM 修复格式错误的代码

java - "RSA/ECB/OAEPWITHSHA256ANDMGF1PADDING"和 "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"有什么区别

java - 无法在 google reCAPTCHA 中将其转换为 Executor

java - 如何在 PostgresQL 中将 outlook 邮件消息作为元素插入一行

java - SonarQube:仅有条件地调用方法