2
votes

I am creating a encryption/decryption method using bouncy castle for j2me. I have created private / public keys using openssl and hard coding into the code. Encryption is working fine (I am getting encrypted string), but when I try decryption for that ciphertext I am getting below exception

org.bouncycastle.crypto.InvalidCipherTextException: unknown block type
 - org.bouncycastle.crypto.encodings.PKCS1Encoding.decodeBlock(PKCS1Encoding.java:362)
 - org.bouncycastle.crypto.encodings.PKCS1Encoding.processBlock(PKCS1Encoding.java:166)
 - com.ust.CryptoJ2me.RSADecrypt(CryptoJ2me.java:564)

PFB the code snippet

public byte[] RSAEncrypt(byte[] toEncrypt) throws Exception {
    String cipherStr;
    String modStr ="AA878F0D9........";
    String expStr = "10001";
    BigInteger modulus = new BigInteger(modStr,16);
    BigInteger exponent = new BigInteger(expStr,16);
    System.out.println("modulus = "+modulus+"// exponent = "+exponent);
    RSApubKey = new RSAKeyParameters(false,modulus,exponent);

    if (RSApubKey == null)
        throw new Exception("Generate RSA keys first!");

    AsymmetricBlockCipher eng = new RSAEngine();
    eng = new PKCS1Encoding(eng);
    eng.init(true, RSApubKey);
    byte[] cipherByte = eng.processBlock(toEncrypt, 0, toEncrypt.length);
    return cipherByte;//cipherStr;
}

public String RSADecrypt (byte[] toDecrypt) throws Exception {
    System.out.println("toDecrypt = "+toDecrypt);
    //byte[] toDecByte = toDecrypt.getBytes("UTF-8");
    //System.out.println("toDecByte ="+toDecByte);
    String plainText;
    BigInteger RSAmod = new BigInteger("00d1aec38b8d189a0a1..",16);
    BigInteger RSAprivExp  = new BigInteger("2d7af1b1283688dadc16..",16);
    BigInteger RSApubExp = new BigInteger("10001",16);
    BigInteger RSAdp = new BigInteger("00f5847cc67ea018f10f16..",16);
    BigInteger RSAdq = new BigInteger("00daa299bf356c6c6db6a21..",16);
    BigInteger RSAp = new BigInteger("00e28dd601e878dd6b1c0c..",16);
    BigInteger RSAq  = new BigInteger("400ff2e2df018507e4c2be6..",16);
    BigInteger RSAqInv   = new BigInteger("00cf4b2ba101efb2378aee..",16);
    RSAPrivateCrtKeyParameters RSAprivKey = new RSAPrivateCrtKeyParameters(RSAmod, RSApubExp,
            RSAprivExp, RSAp, RSAq, RSAdp, RSAdq, RSAqInv);

  AsymmetricBlockCipher eng = new RSAEngine();

  eng = new PKCS1Encoding(eng);

  eng.init(false, RSAprivKey);
  byte[] plainByte = eng.processBlock(toDecrypt, 0, toDecrypt.length);
  plainText = new String(plainByte);

  return plainText;
}
1

1 Answers

3
votes

The modulus doesn't match between public key and private key. It should match. The private key modulus is probably smaller (assuming big endian notation and same length hex strings) and that is why you're getting this error message. Since the private key contains the modulus and public exponent components, you can replace them in the encryption code and see if the decryption works with a new ciphertext.

RSA works by raising some message to a power e (public exponent) modulo m. This results in ciphertexts that are smaller than m, but close to it. The decryption works by raising the ciphertext to the power of d (private exponent) modulo m (the same modulus).

If the private key modulus is much smaller than the public key modulus, the ciphertexts will be bigger and it cannot be decrypted. Mathematically it is possible to "decrypt" the ciphertexts, but you won't get your original plaintext back. The library probably warns you about this.