解码RSA加密字符串 - BadPaddingException:消息大于模数

时间:2017-03-23 23:20:11

标签: java encryption cryptography

我是加密场景的新手。我试图将DecryptStringTest方法从文章Code Project - Cryptography with certificates移植到java。

我从RSA xml格式加载私钥(通过c#生成)。我将这些值放在包含模数,指数,p,q,dp,dq,inverseQ和d的RsaKeyValue类中。

每次我运行它decrypt(),然后传递加密的String,我都会遇到这个异常:

  

BadPaddingException:消息大于模数。

密钥大小为1024.我不明白为什么当使用在c#中使用私钥生成的公钥加密字符串时,它首先给出了我的错误。消息怎么可能比模数大?也许我没有错误地加载我的RSA密钥?

任何见解都会很棒。谢谢!

PS我将清理我的代码。对不起,如果看起来很难看。我只想要这件事。

到目前为止,我的代码看起来像这样。

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;

public class RsaKeys {
private final String rsaDecAlgorithm = "RSA";
private static KeyFactory kf;
private static Cipher cipher;

public PublicKey publicKey;
public PrivateKey privateKey;
private RsaKeyValue rsaKeyVal = new RsaKeyValue();

public RsaKeys(String path) {
    this.rsaKeyVal = new RsaKeyValue(path);
    this.privateKey = makePrivateKey();
    //this.privateKey = makePrivateKeyTwo();
    this.publicKey = makePublicKey();

}

public String encryptString(byte[] input) {
    try {
        cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] ret = cipher.doFinal(input);
        return Base64.encodeBase64String(ret);

    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return null;

}

public String decrypt(String encryptedString) {
    try {
        cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
    } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    int base64BlockSize = (this.rsaKeyVal.getBitStrength() / 8) % 3 != 0
            ? (((this.rsaKeyVal.getBitStrength() / 8) / 3) * 4) + 4
            : (((this.rsaKeyVal.getBitStrength() / 8)) / 3) * 4;

    int iterations = encryptedString.length() / base64BlockSize;
    List<byte[]> temp = new ArrayList<byte[]>();

    /**/
    System.out.println("base64BlockSize: " + base64BlockSize);
    System.out.println("Iterations: " + iterations);
    /**/

    for (int i = 0; i < iterations; i++) {
        try {
            byte[] bytesArray = Base64
                    .decodeBase64(encryptedString.substring(base64BlockSize * i, base64BlockSize));

            /**/
            System.out.println("Byte Array Encrypted String Length: " + bytesArray.length);
            System.out.println("Encoded Byte Array Encrypted String: " + Base64.encodeBase64String((bytesArray)));
            /**/

            temp.add(cipher.doFinal(bytesArray));

        } catch (IllegalBlockSizeException e) {

            e.printStackTrace();
        } catch (BadPaddingException e) {

            e.printStackTrace();
        }
    }

    ByteArrayOutputStream bStr = new ByteArrayOutputStream();
    byte[] retBal = null;
    try {

        temp.stream().forEach(x -> {
            try {
                bStr.write(x);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        });

        retBal = bStr.toByteArray();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            bStr.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    return Base64.encodeBase64String(retBal).toString();
}

public String getPrivateKeyModulus() {
    RSAPrivateKey temp = (RSAPrivateKey) privateKey;
    return "Modulus: " + temp.getModulus();
}

private PublicKey makePublicKey() {

    try {
        byte[] modBytes = Base64.decodeBase64(this.rsaKeyVal.getModulus());
        byte[] expBytes = Base64.decodeBase64(this.rsaKeyVal.getExponent());

        kf = KeyFactory.getInstance(rsaDecAlgorithm);

        BigInteger mod = new BigInteger(1, modBytes);
        BigInteger exp = new BigInteger(1, expBytes);

        RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(mod, exp);
        PublicKey pubKey = kf.generatePublic(pubSpec);

        return pubKey;
    } catch (InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return null;
}

private PrivateKey makePrivateKey() {

    try {
        byte[] modBytes = Base64.decodeBase64(this.rsaKeyVal.getModulus());
        byte[] dBytes = Base64.decodeBase64(this.rsaKeyVal.getD());

        kf = KeyFactory.getInstance(rsaDecAlgorithm);

        BigInteger mod = new BigInteger(1, modBytes);
        BigInteger d = new BigInteger(1, dBytes);

        RSAPrivateKeySpec privSpec = new RSAPrivateKeySpec(mod, d);
        PrivateKey pKey = kf.generatePrivate(privSpec);

        return pKey;
    } catch (InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 

    return null;
}

private PrivateKey makePrivateKeyTwo() {

    byte[] modBytes = Base64.decodeBase64(this.rsaKeyVal.getModulus());
    byte[] expBytes = Base64.decodeBase64(this.rsaKeyVal.getExponent());
    byte[] dBytes = Base64.decodeBase64(this.rsaKeyVal.getD());
    byte[] pBytes = Base64.decodeBase64(this.rsaKeyVal.getP());
    byte[] qBytes = Base64.decodeBase64(this.rsaKeyVal.getQ());
    byte[] dpBytes = Base64.decodeBase64(this.rsaKeyVal.getDp());
    byte[] dqBytes = Base64.decodeBase64(this.rsaKeyVal.getDq());
    byte[] inverseQBytes = Base64.decodeBase64(this.rsaKeyVal.getInverseQ());

    BigInteger mod = new BigInteger(1, modBytes);
    BigInteger exp = new BigInteger(1, expBytes);
    BigInteger d = new BigInteger(1, dBytes);
    BigInteger p = new BigInteger(1, pBytes);
    BigInteger q = new BigInteger(1, qBytes);
    BigInteger dp = new BigInteger(1, dpBytes);
    BigInteger dq = new BigInteger(1, dqBytes);
    BigInteger inverseQ = new BigInteger(1, inverseQBytes);

    RSAPrivateCrtKeySpec keySpec = 
            new RSAPrivateCrtKeySpec(
                    mod,
                    exp,
                    d,
                    p,
                    q,
                    dp,
                    dq,
                    inverseQ
                    );

    try {
        kf = KeyFactory.getInstance(rsaDecAlgorithm);
        PrivateKey key = kf.generatePrivate(keySpec);

        return key;
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return null;
}
}

异常堆栈:

  

javax.crypto.BadPaddingException:消息大于模数       at sun.security.rsa.RSACore.parseMsg(RSACore.java:214)       at sun.security.rsa.RSACore.priCrypt(RSACore.java:144)       在sun.security.rsa.RSACore.rsa(RSACore.java:124)       在com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:362)       在com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)       在javax.crypto.Cipher.doFinal(Cipher.java:2165)       在Entities.RsaKeys.decrypt(RsaKeys.java:72)       在DecryptTest.getRsaPrivateKey(DecryptTest.java:36)       在DecryptTest.testOne(DecryptTest.java:26)       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)       at java.lang.reflect.Method.invoke(Method.java:498)       在org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50)       在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)       在org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)       在org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)       在org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)       在org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)       在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)       在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)       在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)       在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)       在org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)       在org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)       在org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)       在org.junit.runners.ParentRunner.run(ParentRunner.java:363)       在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)       在org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

更改了代码。增加了加密能力。现在可以打印解密的字符串(如果使用代码加密)。还添加了另一种制作私钥的方法。

一直在玩它。我可以成功加密和解密随机字符串。

0 个答案:

没有答案
相关问题