Created
April 14, 2017 06:59
Show how to create a BCRSAPrivateCrtKey instance by Java Reflect API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Constructor; | |
import java.lang.reflect.Field; | |
import java.math.BigInteger; | |
import org.bouncycastle.crypto.DataLengthException; | |
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; | |
import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey; | |
public class RSATest { | |
public static void main(String[] args) throws Throwable { | |
Constructor<BCRSAPrivateCrtKey> c0 = BCRSAPrivateCrtKey.class | |
.getDeclaredConstructor(new Class[] { RSAPrivateCrtKeyParameters.class }); | |
c0.setAccessible(true); | |
// BigInteger modulus = | |
// BigInteger publicExponent, | |
// BigInteger privateExponent, | |
// BigInteger p, | |
// BigInteger q, | |
// BigInteger dP, | |
// BigInteger dQ, | |
// BigInteger qInv) | |
BigInteger modulus = getBI( | |
"848ea1162713230552139bf37b18152fdbd03703103516510269bde5f80e742d0b2796721eda900bcc6dc6b6ad89a206a6bb2be1ed551d3263b802106ffec89f08be8f0d4fdaee19329950bd3d62b60c02151a9d650c7c296075938aa569de88cb8988bd2553dd2e9bb629df6294cbeef8ed1fbdd2c8f3ce9104a8e775eafafd"); | |
BigInteger publicExponent = getBI("10001"); | |
BigInteger privateExponent = getBI( | |
"32ca4fb0a44231ddfd07e46e5390f3b545bd2f06ee73d8dc2b5786da91c440016e4fb9d67a39f68d7ec3e52ae3ad63b6b6b5eae7833f6493851fe1329926ff895a61ca2d58c9bc94a78dd51af452cfaa7a50f6b884bd2939c5ef36712c2afd29e66581bd5ecd82a498b49d4bd1a42f0714148acfd9d95a34a02ea76b453ebfc5"); | |
BigInteger p = getBI( | |
"c932a60cf84dba933f475a347e308beb80b7c21ca9f223db461897b54c860c054543b1d6d19c0b2a2abcc39536daa5b218a89e4ec034b0bcad0caef965f9780b"); | |
BigInteger q = getBI( | |
"a8a9b95c255cae46291f7e0b759a40bf0364dbde0745633198cc6889324fb8531a9f590c05892cc7ad5864e37d7553fd35756bc9547c6d17c23b3ec69778d617"); | |
BigInteger dP = getBI( | |
"63d53cedbc9b9d138957975beaad9e100a3ba416e300e267e05d3d91d959be47333a46d92802fccb3c8f93a0cbaa2c83b5969d8ec7f29d2bd1d634504e183e47"); | |
BigInteger dQ = getBI( | |
"45e32e1f748bd6dad3a76cff2a97e444420fc4db577ff4fe54263f1aba72361a996975e87952c1ef6b70b93d5a7b077660746b595d5cc1879ac019df085cd5b9"); | |
BigInteger qInv = getBI( | |
"10d6b2b9e740e1b4cb1783b19290d8b65918537f4e78a40f53d37fb37171be2806584d5d1ed28e1f5f8945d93a128e8877367d74f577ca1c1145d4a70e4b19d9"); | |
RSAPrivateCrtKeyParameters param = new RSAPrivateCrtKeyParameters(modulus, publicExponent, privateExponent, p, | |
q, dP, dQ, qInv); | |
BCRSAPrivateCrtKey privateKey = c0.newInstance(new Object[] { param }); | |
// setPrivateFieldValue(privateKey, "modulus", modulus); | |
// setPrivateFieldValue(privateKey, "publicExponent", publicExponent); | |
// setPrivateFieldValue(privateKey, "privateExponent", privateExponent); | |
// setPrivateFieldValue(privateKey, "primeP", p); | |
// setPrivateFieldValue(privateKey, "primeQ", q); | |
// setPrivateFieldValue(privateKey, "primeExponentP", dP); | |
// setPrivateFieldValue(privateKey, "primeExponentQ", dQ); | |
// setPrivateFieldValue(privateKey, "crtCoefficient", qInv); | |
int blockSize = getInputBlockSize(modulus, false); | |
byte[] in = { -122, 110, 46, -120, 104, 0, -47, -82, 114, -72, -50, 11, -17, -82, 90, 83, -84, 64, -70, -102, | |
-8, -87, -107, 53, 58, -110, -38, 45, -114, -2, 1, -58, -41, 69, 49, 79, 115, 15, 34, -86, -26, 106, 86, | |
74, -22, -82, 70, -54, -72, -87, 96, 8, -24, -34, -18, 10, -45, 72, 95, 83, -108, -72, 122, 109, 91, | |
-51, -70, 34, -33, 64, -22, 98, -110, -72, 113, -20, 3, -115, -56, 61, -44, -62, 95, -61, -81, 120, 72, | |
73, -112, 63, -112, -108, -16, 79, -5, -71, -92, -41, 29, -85, 92, -125, 23, 71, 46, 112, -95, 14, -109, | |
-94, 81, 56, -118, 19, -65, -80, -121, -17, 121, 2, -24, 107, -34, 115, 26, -92, 7, -14 }; | |
convertInput(in, 0, 128, modulus, false); | |
String data = "866e2e886800d1ae72b8ce0befae5a53ac40ba9af8a995353a92da2d8efe01c6d745314f730f22aae66a564aeaae46cab8a96008e8deee0ad3485f5394b87a6d5bcdba22df40ea6292b871ec038dc83dd4c25fc3af784849903f9094f04ffbb9a4d71dab5c8317472e70a10e93a251388a13bfb087ef7902e86bde731aa407f2"; | |
String password = RSAUtils.decryptByPrivateKey(data, privateKey); | |
System.out.println(password); | |
} | |
public static int getInputBlockSize(BigInteger modulus, boolean forEncryption) { | |
int bitSize = modulus.bitLength(); | |
if (forEncryption) { | |
return (bitSize + 7) / 8 - 1; | |
} else { | |
return (bitSize + 7) / 8; | |
} | |
} | |
public static BigInteger convertInput(byte[] in, int inOff, int inLen, BigInteger modulus, boolean forEncryption) { | |
if (inLen > (getInputBlockSize(modulus, forEncryption) + 1)) { | |
throw new DataLengthException("input too large for RSA cipher."); | |
} else if (inLen == (getInputBlockSize(modulus, forEncryption) + 1) && !forEncryption) { | |
throw new DataLengthException("input too large for RSA cipher."); | |
} | |
byte[] block; | |
if (inOff != 0 || inLen != in.length) { | |
block = new byte[inLen]; | |
System.arraycopy(in, inOff, block, 0, inLen); | |
} else { | |
block = in; | |
} | |
BigInteger res = new BigInteger(1, block); | |
if (res.compareTo(modulus) >= 0) { | |
throw new DataLengthException("input too large for RSA cipher."); | |
} | |
return res; | |
} | |
private static BigInteger getBI(String value) { | |
return new BigInteger(value, 16); | |
} | |
private static void setPrivateFieldValue(Object obj, String fieldName, Object value) | |
throws NoSuchFieldException, IllegalAccessException { | |
Field field = BCRSAPrivateCrtKey.class.getDeclaredField(fieldName); | |
field.setAccessible(true); | |
field.set(obj, value); | |
field.setAccessible(false); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment