gpt4 book ai didi

Generate public and private key and get private key signature(生成公钥和私钥并获取私钥签名)

转载 作者:bug小助手 更新时间:2023-10-26 20:51:37 26 4
gpt4 key购买 nike



I want to use org.bouncycastle:bcprov-jdk15on:1.54 in order to generate a public and private key with Bouncy castle.

我想使用org.bouncyCastle:bcprov-jdk15on:1.54来生成带有bouny Castle的公钥和私钥。


I tried to follow this tutorial: https://www.baeldung.com/java-bouncy-castle but several things are not clear.

我尝试遵循这个教程:https://www.baeldung.com/java-bouncy-castle,但有几件事不清楚。


How I can generate a public and private key without using CLI. Can I do this using only Java code and after that get the signature? I don't need to have a .cer or .csr files. I need ot no this in memory.

如何不使用CLI生成公钥和私钥。我可以只使用Java代码来完成这项工作,然后获得签名吗?我不需要有.ercer或.csr文件。我不需要把这些记在记忆里。


EDIT: I tried this code:

编辑:我尝试了以下代码:


import io.jsonwebtoken.lang.Assert;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.jupiter.api.Test;

import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Base64;

public class CertificateGenerateTestApiTest {

String data; // complete certificate and metadata. We need to get of when we generate a certificate
String signature; // signature of the certificate

@Test
public void certificateGenerationTest()
{
// Generate private and public keys
KeyPair keyPair = generateCertificate();

PublicKey publicCertificate = keyPair.getPublic();

// Problem 1 - think how to populate "data" variable from public certificate
// Problem 2 - think how to populate "signature" variable from public certificate

// Get public key as byte[] in order later on to be stored into DB
byte[] originalPublicCertificate = privateCertificateToByte(publicCertificate);

// Let's say we received some certificate by some web client, and we want to verify it against our original certificate
byte[] secondPublicCertificateReceivedByClient = cloneByteArrayData(originalPublicCertificate);

// Verify certificate
Assert.isTrue(verifyCertificate(secondPublicCertificateReceivedByClient));
}

private KeyPair generateCertificate()
{
try {
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
keyPairGenerator.initialize(2048, new SecureRandom());

KeyPair keyPair = keyPairGenerator.generateKeyPair();

return keyPair;
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
e.printStackTrace();
}
return null;
}

private boolean verifyCertificate(byte[] secondPublicCertificateReceivedByClient)
{
PublicKey publicKey = getKeyPayload(byteToString(secondPublicCertificateReceivedByClient));
boolean verified = false;

try {
verified = verifySignature(data.getBytes("UTF8"), publicKey,
DatatypeConverter.parseHexBinary(signature));
} catch (SignatureException | UnsupportedEncodingException e) {

} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
return verified;
}

private boolean verifySignature(byte[] data, PublicKey key, byte[] signature)
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
Signature signer = Signature.getInstance("SHA1withDSA");
signer.initVerify(key);
signer.update(data);
try {
if (signer.verify(signature)) {
return true;
}
} catch (SignatureException e) {
e.printStackTrace();
}
return false;
}

private PublicKey getKeyPayload(String certificateString) {
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
ByteArrayInputStream bis =
new ByteArrayInputStream(certificateString.getBytes(StandardCharsets.UTF_8));

Certificate certificate = null;
while (bis.available() > 0) {
certificate = cf.generateCertificate(bis);
}

return (certificate == null) ? null : certificate.getPublicKey();
} catch (CertificateException e) {
e.printStackTrace();
}
return null;
}

private String byteToString(byte[] publicKeyBytes)
{
return Base64.getEncoder().encodeToString(publicKeyBytes);
}

private byte[] privateCertificateToByte(PublicKey publicCertificate)
{
return publicCertificate.getEncoded();
}

/**
* Clone byte[] data
*/
private byte[] cloneByteArrayData(byte[] sourceArray)
{
int sourceOffset = 0; /* Starting index in the source array */;
int destinationOffset = 0; // Starting index in the destination array
byte[] destinationArray = new byte[sourceArray.length];

for (int i = 0; i < sourceArray.length; i++) {
destinationArray[destinationOffset + i] = sourceArray[sourceOffset + i];
}

return destinationArray;
}
}

I get:

我得到了:


java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: Empty input

更多回答

(1) 1.54 is almost a decade old; the latest release is 1.75 (2) you can generate a keypair using the standard JCA API KeyPairGenerator.getInstance(algorithm,"BC") or the Bouncy 'lightweight' API which varies depending on the algorithm which you didn't tell us (3) yes you can do this in Java code (or anything else that compiles to JVM code, e.g. Kotlin); show what you're trying to do and exactly how it doesn't work (compile error? runtime exception -- with stacktrace? wrong output -- what is it and what should it be?

(1)1.54是近十年前的版本;最新版本是1.75(2)您可以使用标准JCA API KeyPairGenerator.getInstance(算法,“BC”)或弹性的“轻量级”API生成密钥对,该API根据您没有告诉我们的算法而有所不同(3)是的,您可以在Java代码(或任何其他编译为JVM代码的代码,例如Kotlin)中做到这一点;展示您正在尝试做什么以及它到底是如何工作的(编译错误?运行时异常--使用堆栈跟踪?错误的输出--它是什么,应该是什么?

I tries this stackoverflow.com/questions/76963370/… but I can't get the signature. Can you show me how to get the same result using JVM default classes, please?

我尝试了一下Stackoverflow.com/Questions/76963370/…但我拿不到签名。您能告诉我如何使用JVM默认类获得相同的结果吗?

That Q (#76963370) is about a certificate, and the signature on the certificate, not a keypair. It sounds like what you really want is to generate a certificate, possibly a self-signed certificate although you aren't clear. Your baeldung link uses the openssl program to generate key and self-signed cert, or more simply you can just use the -genkeypair option of keytool -- it actually generates both a keypair and a self-signed cert. But with the standard Java (JCA) classes you can only generate the keypair NOT a cert. Per your link you can do a cert with Bouncy bcprov PLUS bcpkix.

Q(#76963370)是关于证书和证书上的签名的,而不是密钥对。听起来您真正想要的是生成一个证书,可能是一个自签名证书,尽管您不清楚。你的baeldung链接使用openssl程序来生成密钥和自签名证书,或者更简单地说,你可以使用keytool的-genkeypair选项--它实际上同时生成一个密钥对和一个自签名证书。但是使用标准Java(JCA)类,您只能生成密钥对而不是证书。根据您的链接,您可以使用Bouncy bcprov PLUS bcpkix进行认证。

You're still not making sense. There is no such thing as a private certificate, nor a signature of one. Moreover you can't both need and not need something.

你还是说不通。没有私人证书,也没有私人证书的签名。此外,你不能既需要又不需要某样东西。

Peter, please take some more time to formulate a clear question. Learn the basic difference between the terms "key" and "certificate" and decide what you want. Please do not just mix the terms and confuse everyone, including yourself. Otherwise, nobody can answer your question. It would also help to avoid the XY problem by explaining which basic problem you want to solve, not to focus on how you think you should solve it.

彼得,请再花点时间提出一个明确的问题。了解术语“密钥”和“证书”之间的基本区别,并决定您想要什么。请不要混淆术语,混淆每个人,包括你自己。否则,没有人能回答你的问题。通过解释你想解决的基本问题,而不是专注于你认为你应该如何解决它,这也有助于避免XY问题。

优秀答案推荐

Your code is quite chaotic with regard to naming. You cannot magically turn a key into a certificate just by naming it so. You create a key pair and fetch the public key, always calling it a certificate. An apple is not an orange, even if you call it one.

您的代码在命名方面相当混乱。您不能仅仅通过命名就能神奇地将密钥转换为证书。您创建一个密钥对并获取公钥,始终将其称为证书。苹果不是橙子,即使你把它叫做橙子。


Anyway, you did not post your full stack trace. If you had, it would have been apparent why your program throws this exception:

无论如何,您没有发布完整的堆栈跟踪。如果您有,那么您的程序抛出这个异常的原因就很明显了:


java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: Empty input
at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:114)
at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
at CertificateGenerateTestApiTest.getKeyPayload(CertificateGenerateTestApiTest.java:98)
at CertificateGenerateTestApiTest.verifyCertificate(CertificateGenerateTestApiTest.java:61)
at CertificateGenerateTestApiTest.main(CertificateGenerateTestApiTest.java:45)
Caused by: java.io.IOException: Empty input
at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:110)
... 4 more
Exception in thread "main" java.lang.NullPointerException
at CertificateGenerateTestApiTest.verifyCertificate(CertificateGenerateTestApiTest.java:65)
at CertificateGenerateTestApiTest.main(CertificateGenerateTestApiTest.java:45)

My line numbers are a bit different after pasting your code into my IDE and adjusting a few things to make it run without JUnit, but the basic information stays the same:

在将代码粘贴到我的IDE中并调整了一些设置以使其在没有JUnit的情况下运行后,我的行号有点不同,但基本信息保持不变:


You never initialise the data field in your class, but are trying to call data.getBytes("UTF8"). That cannot work.

您从未初始化类中的数据字段,而是尝试调用data.getBytes(“UTF8”)。这是行不通的。


There are many other problems in your code, but this one answers your question why this error message occurs.

您的代码中还有许多其他问题,但这个问题回答了您为什么会出现此错误消息的问题。


更多回答

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com