java - BouncyCaSTLe 签名 : java. security.InvalidKeyException: key 格式无效

标签 java

我正在 BouncyCaSTLe JCE 下使用 RSA 签署我的数据。

我已使用发送者的私钥对其进行签名,并使用发送者的公钥进行验证。

我已使用以下代码成功签署内容:

签名功能

public static String sign(String plainText, PrivateKey privateKey) throws Exception {

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        Signature privateSignature = Signature.getInstance("SHA256withRSA");
        privateSignature.initSign(privateKey);
        privateSignature.update(plainText.getBytes("UTF-8"));

        byte[] signature = privateSignature.sign();

        return Base64.getEncoder().encodeToString(signature);
    }

签名来电

String sign = sign( filehash , getPrivate( ibftSenderPrivateKeyPath, "RSA" ) );

获取私有(private)函数

public static  PrivateKey getPrivate(String filename, String algorithm) throws Exception {

        byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance(algorithm);
        return kf.generatePrivate(spec);
}

现在,当我使用发件人的公钥验证消息时,它会引发异常。

验证码调用方

boolean bool = verify(decyrptehash, signature, getPublic( senderPublicPath, "RSA" ) );

验证功能

public static  boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

    Signature publicSignature = Signature.getInstance("SHA256withRSA");
    publicSignature.initVerify(publicKey);
    publicSignature.update(plainText.getBytes("UTF-8"));

    byte[] signatureBytes = Base64.getDecoder().decode(signature);

    return publicSignature.verify(signatureBytes);
}

获取公共(public)函数

public static PublicKey getPublic(String filename, String algorithm) throws Exception {

        byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance(algorithm);
        return kf.generatePublic(spec);

    }

key 生成

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;

import Decoder.BASE64Encoder;

public class GenerateRSAKeys{

    public static void main(String[] args)
    {



        String publicKeyFilename = null;
        String privateKeyFilename = null;

        publicKeyFilename = "C:\\Users\\imjme1\\Desktop\\Work_backup\\FMS\\EPM_FILE_ENCRYPTION\\NIFT_SOLUTION\\sender_keys\\receiver_publicKey";
        privateKeyFilename = "C:\\Users\\imjme1\\Desktop\\Work_backup\\FMS\\EPM_FILE_ENCRYPTION\\NIFT_SOLUTION\\sender_keys\\receiver_privateKey";

        GenerateRSAKeys generateRSAKeys = new GenerateRSAKeys();

        generateRSAKeys.generate(publicKeyFilename, privateKeyFilename);

    }

    private void generate (String publicKeyFilename, String privateFilename){

        try {

            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

            // Create the public and private keys
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
            BASE64Encoder b64 = new BASE64Encoder();

            SecureRandom random = createFixedRandom();
            generator.initialize(1024, random);

            KeyPair pair = generator.generateKeyPair();
            Key pubKey = pair.getPublic();
            Key privKey = pair.getPrivate();

            System.out.println("publicKey : " + b64.encode(pubKey.getEncoded()));
            System.out.println("privateKey : " + b64.encode(privKey.getEncoded()));

            BufferedWriter out = new BufferedWriter(new FileWriter(publicKeyFilename));
            out.write(b64.encode(pubKey.getEncoded()));
            out.close();

            out = new BufferedWriter(new FileWriter(privateFilename));
            out.write(b64.encode(privKey.getEncoded()));
            out.close();


        }
        catch (Exception e) {
            System.out.println(e);
        }
    }

    public static SecureRandom createFixedRandom()
    {
        return new FixedRand();
    }

    private static class FixedRand extends SecureRandom {

        MessageDigest sha;
        byte[] state;

        FixedRand() {
            try
            {
                this.sha = MessageDigest.getInstance("SHA-1");
                this.state = sha.digest();
            }
            catch (NoSuchAlgorithmException e)
            {
                throw new RuntimeException("can't find SHA-1!");
            }
        }

        public void nextBytes(byte[] bytes){

            int    off = 0;

            sha.update(state);

            while (off < bytes.length)
            {                
                state = sha.digest();

                if (bytes.length - off > state.length)
                {
                    System.arraycopy(state, 0, bytes, off, state.length);
                }
                else
                {
                    System.arraycopy(state, 0, bytes, off, bytes.length - off);
                }

                off += state.length;

                sha.update(state);
            }
        }
    }

}

最佳答案

您当前的问题是您使用 Base 64 将公钥写入文件,而您在读取公钥后忘记对其进行解码。

关于java - BouncyCaSTLe 签名 : java. security.InvalidKeyException: key 格式无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61184296/

相关文章:

java - 尝试读取文本文件时输出错误

java - 类加载器加载错误的文件

java - 是否需要在 SWT 复合构造函数中调用 pack()/layout() ?

java - EnableEurekaServer 导入不存在

java - 同步三个线程

java - Solr 选择只返回 id

java - 如何设置我在加载其他 jframe 类时 setvisible(false) 的 JFrame?

java - 如何在java中给出时间戳值作为参数?

java - 从没有 API 的网站检索信息

java - awk - 打印匹配行时出现问题