当前位置: 首页 > 知识库问答 >
问题:

使用rsa密钥解密字符串

吕岳
2023-03-14
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 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;
        }
    }

userData.json:

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

共有1个答案

麹凯捷
2023-03-14

由于我对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;
        }
    }
 类似资料:
  • 我有一个公钥和一个私钥,还有一个字符串,我想要解密。 公钥的格式如下: 私钥的格式如下: 我要解密的字符串已经使用公钥加密,然后我需要使用私钥解密它。

  • 我设置了Azure密钥库来检索RSA密钥进行加密。Azure发送给我一个KeyBundle类型的对象。此对象包含一个大小为2048的RSA类型的JsonWebKey。查看我的RSA密钥,它有两个方法,称为和。现在我正在尝试加密和解密一个简单的字符串,如下所示: 在System.Security.Cryptography.RSAImplementation.RSACNG.EncryptorDecry

  • 我一直在搜索,但我似乎找不到一个简单的方法解密使用RSA。 我生成了一个公钥和私钥,它们存储在两个单独的文件中,并且是XML格式的。使用FromXmlString将公钥关联到RSACryptoServiceProvider对象,然后加密一个字符串,这一点没有问题。当我试图解密一个加密的字符串时,我的困惑就来了。我不确定如何将私钥数据与RSACryptoServiceProvider关联,以便使用D

  • 但这总是给我以下的例外- 我的键盘生成逻辑- 我的加密逻辑- Base64 Util方法-

  • 问题内容: 我正在编写一个用于传输文件的小型应用程序,或多或少地将其作为一种学习更多编程加密基础的方法。这个想法是生成一个RSA密钥对,交换公共密钥,并发送AES iv和密钥以进一步解密。我想用接收者的RSA公钥加密AES密钥,如下所示: 然后,我将密钥值写给接收器,并按如下方式解密: 在控制台的另一端,我将其作为输出: 此外,如果我创建一个大小为16的字节数组,并将cipher.doFinal(

  • 我有一个RSA公钥证书。我可以使用具有。PEM扩展名或仅将其用作具有以下格式的字符串: 启动RSA公共密钥 {KEY} -----结束RSA公钥----- 我试图使用此密钥向服务器发送加密的JSON。我尝试了许多其他相关堆栈溢出问题的解决方案,但没有一个答案不适合我。这个答案似乎有道理https://stackoverflow.com/a/43534042,但有些东西不能正常工作,可能是因为X50