My application receives the raw pieces of a public RSA key (n and e) and needs to use these to encrypt a cipher text. I've been trying to use BouncyCastle but my code isn't working. The problem arises in trying to create the X509EncodedKeySpec.
Can anyone help me get this working? Here's the code I have:
public static PublicKey getPublicKeyFromString(String key) throws Exception
{
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64Encoder.decode(key));
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
return publicKey;
}
I guess the real problem is that n and e are separate and I don't know how to combine them.
Why are you not using new RSAPublicKeySpec(n,e)?
public static PublicKey getPublicKeyFromString(String key) throws Exception
{
BASE64Decoder b64 = new BASE64Decoder();
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64.decodeBuffer(key));
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
return publicKey;
}
Related
I am trying to implement AEPS API but unable to encrypt aadhar number in php. In developer guide they provided method to encrypt using JAVA and i am using php.
Given JAVA code is as follows.
public static String calculateRSA( String salt ) throws InvalidKeyException, Exception {
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, getPublicKey());
byte[] secretMessageBytes = salt.getBytes("UTF-8");
byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessageBytes);
String encodedMessage = Base64.encodeBase64String(encryptedMessageBytes);
return encodedMessage;
}
public static PublicKey getPublicKey() throws Exception {
String rawPublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaFyrzeDhMaFLx+LZUNOOO14Pj9aPfr+1WOanDgDHxo9NekENYcWUftM9Y17ul2pXr3bqw0GCh4uxNoTQ5cTH4buI42LI8ibMaf7Kppq9MzdzI9/7pOffgdSn+P8J64CJAk3VrVswVgfy8lABt7fL8R6XReI9x8ewwKHhCRTwBgQIDAQAB";
byte[] keyBytes = Base64.decodeBase64(rawPublicKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);// generatePrivate(spec);
}
I tried
$publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaFyrzeDhMaFLx+LZUNOOO14Pj9aPfr+1WOanDgDHxo9NekENYcWUftM9Y17ul2pXr3bqw0GCh4uxNoTQ5cTH4buI42LI8ibMaf7Kppq9MzdzI9/7pOffgdSn+P8J64CJAk3VrVswVgfy8lABt7fL8R6XReI9x8ewwKHhCRTwBgQIDAQAB';
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->loadKey($publicKey); // public key
$plaintext = '828409353766';
//$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
$encrypted = $rsa->encrypt($plaintext);
$encrypted = base64_encode($encrypted);
Is it possible to take a public key that I have generated, convert it into a string, reverse the process and use it as a key again?
generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048);
KeyPair keyPair = generator.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Then convert this to a string:
String public = someMethod(publicKey)
and then Reverse it at a later time:
RSAPublicKey newPublicKey = someMethod(public)
You can convert the Public Key to a String as follows.
String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
Then that String can be converted back to a public key as follows.
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey2 = keyFactory.generatePublic(spec);
I've used the following code to convert the public and private key to a string
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);
KeyPair keyPair = keyPairGen.genKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String publicK = Base64.encodeBase64String(publicKey.getEncoded());
String privateK = Base64.encodeBase64String(privateKey.getEncoded());
Now I'm trying to convert it back to public ad private key
PublicKey publicDecoded = Base64.decodeBase64(publicK);
I'm getting error of cannot convert from byte[] to public key. So I tried like this
PublicKey publicDecoded = new SecretKeySpec(Base64.decodeBase64(publicK),"RSA");
This leads to error like below
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: Neither a public nor a private key
Looks like I'm doing wrong key conversion here. Any help would be appreciated.
I don't think you can use the SecretKeySpec with RSA.
This should do:
byte[] publicBytes = Base64.decodeBase64(publicK);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(keySpec);
And to decode the private use PKCS8EncodedKeySpec
Trying to get X509 PublicKey from byte stream using this code.
[Fact]
public void CreatePublicKeyParameters__ShouldReturnPublicKey__WhenPassPublicKeyBytes()
{
ApplePay applePay = new ApplePay(new MOBSHOPApplePayRequest());
byte[] privateKey = Base64.Decode("MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgjyo3fzxT7j+CFxC7I4B5iVee2FUyn2vfOSjcgp2/g6qhRANCAARdoBFEtnuapXFKw4DYWsW0yV4bavpdWKszkefi19AhlIRE3WSNWSn25W5tZNFjMWtLISBmqANyufx2xP19oRvy");
var publickey = applePay.CreatePublicKeyParameters(privateKey);
}
public AsymmetricKeyParameter CreatePublicKeyParameters(byte[] ephemeralPublicKeyBytes)
{
return (ECPublicKeyParameters)PublicKeyFactory.CreateKey(ephemeralPublicKeyBytes);
}
Getting following error
Bad sequence size: 3
Parameter name: seq
BouncyCastle.Crypto
at Org.BouncyCastle.Asn1.X509.SubjectPublicKeyInfo..ctor(Asn1Sequence seq)
at Org.BouncyCastle.Asn1.X509.SubjectPublicKeyInfo.GetInstance(Object obj)
at Org.BouncyCastle.Security.PublicKeyFactory.CreateKey(Byte[] keyInfoData)
Basically, I'm trying to convert this following JAVA code to C#
public ECPublicKey CreatePublicKeyParameters(byte[] ephemeralPublicKeyBytes)
{
KeyFactory keyFactory = KeyFactory.getInstance( "ECDH", "BC" );
X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec( ephemeralPublicKeyBytes );
ECPublicKey ephemeralPublicKey = (ECPublicKey) keyFactory.generatePublic( encodedKeySpec );
return ECPublicKey
}
Please help me.
Sorry, it was wrong test input data. It's working with this below testcase.
[Fact]
public void CreatePublicKeyParameters__ShouldReturnPublicKey__WhenPassPublicKeyBytes()
{
ApplePay applePay = new ApplePay(new MOBSHOPApplePayRequest());
byte[] privateKey = Base64.Decode(
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEl/XAbOgrSCupps/QbIxJ3u4QZ1PlbO5uGDD1zj/JGMoephYSEgw+63gHQHekx3T8duXN3CoYafUpuQlwOeK6/w==");
var publickey = applePay.CreatePublicKeyParameters(privateKey);
}
Thanks
I've created an org.bouncycastle.asn1.pkcs.RSAPrivateKey using its static getInstance(byte[]) from a PKCS#1 formated DER bytes,
now I want to cast(or change) this to PrivateKey, how to do that??
You can directly create the PrivateKey from an ASN.1 encoded bytes array.
public static PrivateKey makeKey(byte[] keyBytes) {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
KeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytes);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return privateKey;
}