gpt4 book ai didi

java - 使用 rsa key 解密字符串

转载 作者:行者123 更新时间:2023-11-30 10:19:17 25 4
gpt4 key购买 nike

我已经使用 RSA 公钥 对一个简单的 json 数据进行了编码,现在我正在尝试对其进行解码。编码部分通过终端完成,解码以编程方式执行。为了验证加密文件的完整性,我通过终端对其进行了解密,它工作正常。现在我正在尝试以编程方式解密文件,但我遇到了解密问题。我可以完美地读取 private_key.pem 文件并将其传递给 Cipher 以解密编码文件,但是在这样做时我得到以下异常。

java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block
at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(CipherSpi.java:457)
at javax.crypto.Cipher.doFinal(Cipher.java:1204)
at com.benchmark.openssl.RSADecryption.decipherString(RSADecryption.java:295)
at com.benchmark.openssl.RSADecryption.main(RSADecryption.java:263)
at com.benchmark.MainActivity$1.onComplete(MainActivity.java:157)
at io.reactivex.internal.operators.completable.CompletableObserveOn$ObserveOnCompletableObserver.run(CompletableObserveOn.java:90)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:463)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)

使用的 OpenSSL 命令:

openssl genrsa -out priv_key.pem 2048  
openssl rsa -pubout -in priv_key.pem -out pub_key.pem
openssl rsautl -encrypt -in userdata.json -out user_encrypted_with_pub_key -inkey pub_key.pem –pubin
openssl rsautl -decrypt -in user_encrypted_with_pub_key -inkey priv_key.pem --> This is what I'm trying to do programmatically.

代码:

import org.spongycastle.util.io.pem.PemObject;
import org.spongycastle.util.io.pem.PemReader;
import android.util.Base64;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public static void main(String privateKeyPath, String encodedFilePath) throws FileNotFoundException,
IOException, NoSuchAlgorithmException, NoSuchProviderException {
Security.addProvider(new BouncyCastleProvider());

String encodedString = readFileAsString(encodedStringPath);
Timber.v("Encoded String: %s", encodedString);

KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
try {
PrivateKey priv = generatePrivateKey(factory, privateKeyPath);
Timber.i(String.format("Instantiated private key: %s", priv));
decipherString(priv, encodedString);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}

private static PrivateKey generatePrivateKey(KeyFactory factory,
String filename) throws InvalidKeySpecException,
FileNotFoundException, IOException {
PemFile pemFile = new PemFile(filename, false);
byte[] content = pemFile.getPemObject().getContent();
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
return factory.generatePrivate(privKeySpec);
}

private static void decipherString(PrivateKey privateKey, String encodedStringData) {
byte[] dectyptedText = null;
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
dectyptedText = cipher.doFinal(encodedStringData.getBytes()); <---- EXCEPTION HERE
Timber.w("Deciphered text is: %s", new String(dectyptedText));
}
catch (Exception e) {
e.printStackTrace();
}
}
static class PemFile {

private PemObject pemObject;

public PemFile(String filename, boolean isBase64) throws FileNotFoundException, IOException {
PemReader pemReader = new PemReader(new InputStreamReader(new FileInputStream(filename)));
try {
this.pemObject = pemReader.readPemObject();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
pemReader.close();
}
}

public PemObject getPemObject() {
return pemObject;
}
}

用户数据.json:

{
"username":"umer",
"password":"123456",
"pin" : "123"
}

最佳答案

由于我对 openssl 了解不多,所以我通过反复试验弄明白了。无论如何,解密加密文件的过程应该如下所示。

终端:

String -> (Encrypt) -> Encrypted String -> (convert to base64) -> EncryptedBase64EncodedString -> (Decrypt) -> Original String

以编程方式:

EncryptedBase64EncodedString -> (convert from base64 to normal string [Use Default parameters only! No Padding or other constants for decoding base64 string]) -> Pass private_key & decoded string to Cipher -> Profit.

结果代码是:

import org.spongycastle.util.io.pem.PemObject;
import org.spongycastle.util.io.pem.PemReader;

import android.util.Base64;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

public static void main(String privateKeyPath, String publicKeyPath, String encodedStringPath, boolean isPublicKeyAndDataBase64) throws FileNotFoundException,
IOException, NoSuchAlgorithmException, NoSuchProviderException {
Security.addProvider(new BouncyCastleProvider());

String encodedString = readFileAsString(encodedStringPath);
if(isPublicKeyAndDataBase64) {
KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
Timber.w("Encoded String converted from base64: %s", decodeBase64ToBytesa(encodedString));
try {
PrivateKey priv = generatePrivateKey(factory, privateKeyPath);
Timber.i(String.format("Instantiated private key: %s", priv));
decipherString(priv, decodeBase64ToBytesa(encodedString));
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return;
}
else
Timber.w("Encoded String: %s", encodedString);

KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
try {
PrivateKey priv = generatePrivateKey(factory, privateKeyPath);
Timber.i(String.format("Instantiated private key: %s", priv));
decipherString(priv, encodedString.getBytes());
PublicKey pub = generatePublicKey(factory, publicKeyPath);
Timber.i(String.format("Instantiated public key: %s", pub));
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}

private static PrivateKey generatePrivateKey(KeyFactory factory,
String filename) throws InvalidKeySpecException,
FileNotFoundException, IOException {
PemFile pemFile = new PemFile(filename, false);
byte[] content = pemFile.getPemObject().getContent();
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
return factory.generatePrivate(privKeySpec);
}

private static PublicKey generatePublicKey(KeyFactory factory,
String filename) throws InvalidKeySpecException,
FileNotFoundException, IOException {
PemFile pemFile = new PemFile(filename, false);
byte[] content = pemFile.getPemObject().getContent();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
return factory.generatePublic(pubKeySpec);
}

private static void decipherString(PrivateKey privateKey, byte[] encodedStringData) {
byte[] dectyptedText = null;
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
dectyptedText = cipher.doFinal(encodedStringData);
Timber.w("Deciphered text is: %s", new String(dectyptedText));
}
catch (Exception e) {
e.printStackTrace();
}
}
static class PemFile {

private PemObject pemObject;

public PemFile(String filename, boolean isBase64) throws FileNotFoundException, IOException {
PemReader pemReader = null;

if(isBase64) {
Timber.i("reading base64 encoded pem file. base64DecodedString: %s", decodeBase64(filename));
pemReader = new PemReader(new StringReader(decodeBase64(filename)));
}
else
pemReader = new PemReader(new InputStreamReader(
new FileInputStream(filename)));
try {
this.pemObject = pemReader.readPemObject();
}
catch (Exception e) {
e.printStackTrace();
}finally {
pemReader.close();
}
}

public PemObject getPemObject() {
return pemObject;
}
}

关于java - 使用 rsa key 解密字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48682003/

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