gpt4 book ai didi

java - java中使用rsa时出现解密错误。

转载 作者:行者123 更新时间:2023-12-02 01:51:27 25 4
gpt4 key购买 nike

我的目标是接收一条包含挑战和起源的消息。收到此消息后,必须生成 rsa key 对,然后使用该 key 对来操作数据,如下所示。使用生成的公钥对数据的某些部分进行加密。在授权期间,必须使用私钥对该数据进行解密。但是,当我尝试解密时,它显示解密错误。我什至打印了代码的不同部分,只是为了检查是否实现了所需的输出,这就是为什么我知道从文件中获取的私钥是正确的。我无法解决解密错误。该任务的规范要求使用 rsa 而不是混合加密。我尝试过填充,但这没有帮助。请教如何解决这个问题

package pam;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.xml.bind.DatatypeConverter;
import com.sun.jersey.core.util.Base64;

class Test
{
public static void kpgen(int numBits, String s) throws Exception
{
if(s.length()!=64)
{
System.out.println("invalid entry");
}
else
{
KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keygen.genKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
System.out.println("pk: "+privateKey);
System.out.println("pubk: "+publicKey);

String fileBase = "f:\\tempKey"; //WRITING PVT KEY TO FILE
try (FileOutputStream out = new FileOutputStream(fileBase + ".key"))
{
out.write(keyPair.getPrivate().getEncoded());
}
try (FileOutputStream out = new FileOutputStream(fileBase + ".pub"))
{
out.write(keyPair.getPublic().getEncoded());
}

System.out.println("Key pair : " + Base64.encode(String.valueOf(keyPair)));
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(keyPair.toString().getBytes(StandardCharsets.UTF_8));
String sha256 = DatatypeConverter.printHexBinary(digest).toLowerCase();
System.out.println("Hash value: "+sha256);

String ch = s.substring(0,32);
String or = s.substring(32,64);
System.out.println("Challenge: "+ch);
System.out.println("Origin: "+or);

MessageDigest md1 = MessageDigest.getInstance("SHA-256");
byte[] digest1 = md1.digest(privateKey.toString().getBytes(StandardCharsets.UTF_8));
String sha = DatatypeConverter.printHexBinary(digest1).toLowerCase();
or = or + sha;
System.out.println("String kh: "+or);

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] keyHandle = cipher.doFinal(or.getBytes());
System.out.println("Key Handle: "+keyHandle);

String f = "f:\\keyList.pub";
Key pub = getKeyFromFile(f);
System.out.println("Attestation Public Key: "+pub);

PrivateKey pk = (PrivateKey) getPvtKey("f:\\keyList.key");
Signature rsa = Signature.getInstance("SHA1withRSA");
rsa.initSign(pk);
rsa.update(ch.getBytes());
byte[] sc = rsa.sign();
System.out.println("Signed challenge: "+sc);

String rm = publicKey.toString() + pub + sc + keyHandle;
System.out.println("Response Msg: " +rm);
}
}
public static Key getKeyFromFile(String fileName) throws Exception
{
byte[] bytes = Files.readAllBytes(Paths.get(fileName));
X509EncodedKeySpec ks = new X509EncodedKeySpec(bytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pub = kf.generatePublic(ks);
return pub;
}
public static PrivateKey getPvtKey(String s) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
byte[] bytes = Files.readAllBytes(Paths.get(s));
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(bytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey pvt = kf.generatePrivate(ks);
return pvt;
}
public static void auth(String s) throws NoSuchAlgorithmException, Exception, IOException
{
String chal = s.substring(0, 32);
String origin = s.substring(32,64);
String kh = s.substring(64);
byte[] kh1 = kh.getBytes();

PrivateKey pvtKey = getPvtKey("f:\\tempKey.key"); //READING THE PRIVATE KEY MADE IN KPGEN
System.out.println("pk: "+pvtKey);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pvtKey);
byte[] keyHandle = cipher.doFinal(kh1);

String or = keyHandle.toString().substring(0, (kh.length()/2));
String pk = keyHandle.toString().substring(kh.length()/2);

int c = 0;
if(or.equals(origin))
{
c++;
}
else
{
System.out.println("Bad Key Handle: Invalid Origin");
}
if(pk.equals(pvtKey.toString()))
{
c++;
}
else
{
System.out.println("Bad Key Handle: invalid private key");
}
if(c==2)
{
Signature rsa = Signature.getInstance("SHA1withRSA");
rsa.initSign((PrivateKey) pvtKey);
rsa.update(chal.getBytes());
byte[] sc = rsa.sign();
System.out.println("Signed Challenge: "+sc);
}
else
System.out.println("error");
}

}

最佳答案

您的代码中存在多个(许多)加密问题

首先 - 正确编码您的数据,Java 中的字符串用于表示可打印字符。一旦您使用加密(在 byte[] 级别上工作),您就需要对值进行编码或解码。

示例 - 您的代码将打印“keyHandle”,它是一个字节数组对象哈希,而不是真正的加密数据本身

byte[] keyHandle = cipher.doFinal(or.getBytes());
System.out.println("Key Handle: "+keyHandle);
...
String rm = publicKey.toString() + pub + sc + keyHandle;

使用十六进制或base64编码来打印输出。这同样适用于签名。

I am unable to solve the decryption error.

String kh = s.substring(64);
byte[] kh1 = kh.getBytes();
..
byte[] keyHandle = cipher.doFinal(kh1);

您只是假设您可以解密一些随机子字符串?使用 RSA 加密将产生 key 大小的输出(例如 2048 位),并且您必须整体存储和解密,而不是任何子字符串。

作为学习练习 - 尝试简单地加密和解密、编码、解码以学习可以(重新)使用的原语。

关于java - java中使用rsa时出现解密错误。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52924324/

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