当前位置: 首页 > 面试题库 >

使用PEM编码的加密私钥对本机签名

从景曜
2023-03-14
问题内容

我正在尝试使用PEM(X.509)证书(存储在磁盘上的privateKey.pem文件中)对通过Java中的套接字通过套接字发送的消息进行签名,但是在找到一个即将结束的示例时遇到了很多麻烦。我通常是C
++的人,他只是介入帮助这个项目,所以对所有不熟悉API的人来说,将它们全部组合成可以工作的代码有点困难。

不幸的是,我仅限于Java(1.6.0 Update
16)中的标准方法,因此尽管我使用BouncyCastle的PEMReader找到了一个类似的示例,但在这个特定项目上并没有太大帮助。

我的privateKey.pem密钥受密码保护,格式为:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED DEK-Info:
DES-EDE3-CBC,63A862F284B1280B
[...]
tsjQI4H8lhOBuk+NelHu7h2+uqbBQzwkPoA8IqbPXUz+B/MAGhoTGl4AKPjfm9gu
OqEorRU2vGiSaUPgDaRhdPKK0stxMxbByUi8xQ2156d/Ipk2IPLSEZDXONrB/4O5
[...]
-----END RSA PRIVATE KEY-----

他们的密钥是使用OpenSSL生成的:

openssl.exe genrsa -out private_key.pem 4096

我无法在运行时之前将此密钥转换为DER或其他格式,任何必需的转换都需要在代码内部进行,因为密钥需要易于替换并且格式将保持为PEM。

我听说过很多我不确定的事情,并希望在这里的集体思想可以帮助把事情分解在一起。

我听说它说PEM证书需要经过Base64解码,才能将其转换为可以使用的DER证书。我有一个称为MiGBase64的Base64解码工具,但不确定如何/何时完成解码。

我迷失在Java
API文档中,试图追踪存在的15种不同类型的密钥,密钥库,密钥生成器,证书等,但是我对它们中的任何一个都不熟悉,无法正确识别我需要使用以及如何一起使用它们。

基本算法看起来很简单,这就是为什么我尤其无法编写同样简单的实现而感到沮丧的原因:

1)从文件中读取privateKey.pem
2)使用密码短语将私钥加载到XXX类中,以对密钥进行解密
3)使用带有Signature类的密钥对象对消息进行签名

非常感谢您提供帮助,尤其是示例代码。我一直在努力寻找有用的例子来解决这个问题,因为大多数“接近”的例子都是使用BouncyCastle生成新的密钥,或者使用不适用于此的其他形式的密钥/类来生成新密钥。

这似乎是一个非常简单的问题,但它使我发疯,有没有真正简单的答案?


问题答案:

如果您使用的是BouncyCastle,请尝试以下操作:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyPair;
import java.security.Security;
import java.security.Signature;
import java.util.Arrays;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PasswordFinder;
import org.bouncycastle.util.encoders.Hex;

public class SignatureExample {

    public static void main(String [] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());

        String message = "hello world";
        File privateKey = new File("private.pem");
        KeyPair keyPair = readKeyPair(privateKey, "password".toCharArray());

        Signature signature = Signature.getInstance("SHA256WithRSAEncryption");
        signature.initSign(keyPair.getPrivate());
        signature.update(message.getBytes());
        byte [] signatureBytes = signature.sign();
        System.out.println(new String(Hex.encode(signatureBytes)));

        Signature verifier = Signature.getInstance("SHA256WithRSAEncryption");
        verifier.initVerify(keyPair.getPublic());
        verifier.update(message.getBytes());
        if (verifier.verify(signatureBytes)) {
            System.out.println("Signature is valid");
        } else {
            System.out.println("Signature is invalid");
        }
    }

    private static KeyPair readKeyPair(File privateKey, char [] keyPassword) throws IOException {
        FileReader fileReader = new FileReader(privateKey);
        PEMReader r = new PEMReader(fileReader, new DefaultPasswordFinder(keyPassword));
        try {
            return (KeyPair) r.readObject();
        } catch (IOException ex) {
            throw new IOException("The private key could not be decrypted", ex);
        } finally {
            r.close();
            fileReader.close();
        }
    }

    private static class DefaultPasswordFinder implements PasswordFinder {

        private final char [] password;

        private DefaultPasswordFinder(char [] password) {
            this.password = password;
        }

        @Override
        public char[] getPassword() {
            return Arrays.copyOf(password, password.length);
        }
    } 
}


 类似资料:
  • 问题内容: 我有一个加密的私钥,并且知道密码。 我需要使用Java库对其进行解密。 不过,我宁愿不要使用BouncyCastle,除非没有其他选择。根据以前的经验,有太多更改,没有足够的文档。 私钥的格式如下: 我相信关键数据是Base64编码的,因为我看到的是64个字符。 我尝试了以下解密密钥: 我得到这个例外 我是否将正确的参数传递给构造函数? 我该如何工作? 我尝试了Ericsonn的建议,

  • 我有一个加密的私钥,我知道密码。 我需要用Java库解密它。 不过,我不想使用BouncyCastle,除非没有其他选择。根据之前的经验,变更太多,文档不足。 私钥的格式如下: 我相信密钥数据是Base64编码的,因为我在64个字符后看到。 我尝试了以下方法来解密密钥: 我得到这个例外 我是否将正确的参数传递给构造函数? 我怎样才能做到这一点? 我尝试了Ericsonn的建议,有一个小的变化,因为

  • 我希望加载/使用Java应用程序中提供给我的加密私钥。请找到密钥(加密的私有密钥、解密的私有密钥和公钥如下所示)。 加密的私钥密码:“AWCTJPET9FL7UBTP97HX99GDOFEWKUF5TUXSUJEST2SEKYVKYINRFRJ6EISUTERF” 密钥是在NodeJS中使用加密生成的,使用: 我正在使用:运行时版本:11.0.7+10-B765.64amd64,OpenJDK 6

  • 我在使用Java Bouncycastle的客户机和使用Python RSA库的密钥服务器之间交换私钥时遇到了困难。PEM格式用于通过REST传输密钥。keyserver无法解密我提供的密钥(加密密码更改时需要),它需要PKCS#1或PKCS#8密钥和PEM,如下所示: 但是BouncyCastle的输出(使用JCEpeEncryptorBuilder和JcaMiscPEMGenerator)的起

  • PEMException:创建加密私钥时出现问题:System.NullReferenceException:对象引用未设置为对象的实例。在org.bouncycastle.openssl.pemreader.readprivateKey(PemObject PemObject) 下面是Decrypt方法的代码:

  • 我试图找到一个工作的javascript库的反应本机,将允许PEM格式的RSA公钥加密。 我不是加密专家,刚开始使用react native,所以如果我碰巧错过了一些明显的东西,请原谅。 到目前为止,我尝试了本文推荐的react native rsa和react native rsa util。 我无法让react-nate-rsa-util工作,react-nate-rsa似乎不接受公共PEM密