I want to implement RSA encryption with public and private key in the android. Implementation I have done is as below.
public static String enccriptData(String dataToEncrypt)
{
try {
String publicExponentString = "AQAB";
String PUBLIC_KEY = "BgIAAACkAABSU0ExAAQAAAEAAQBJGj09Gbyl7BS/8MytvjBUUfaktW984VHHW4lSI9y2OwaeOq4qqSD6IOHU9HL/QtwZ+wELq28eAOQSnr11hifMf6zWjIsCBHOEpLNJjL3wxjl7dUBEGMJOeZj2rmcf8v7lP/rpAtO/G8wKXhAIKLIFxcChkXwQKbQbHQ/FtX2bwg=="
byte[] modulusBytes = Base64.decodeBase64(PUBLIC_KEY);
byte[] exponentBytes = Base64.decodeBase64(publicExponentString);
BigInteger modulus = new BigInteger(1, modulusBytes);
BigInteger publicExponent = new BigInteger(1, exponentBytes);
RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, publicExponent);
KeyFactory fact = null;
fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(rsaPubKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String token = dataToEncrypt + ":" + String.valueOf(getCurrentDateTimeTicks());
byte[] plainBytes = token.getBytes("UTF-16LE");
byte[] cipherData = cipher.doFinal(plainBytes);
String encryptedStringBase64 = Base64.encodeBase64String(cipherData);
return encryptedStringBase64;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
private static long getCurrentDateTimeTicks(){
long TICKS_AT_EPOCH = 621355968000000000L;
long tick = System.currentTimeMillis()*10000 + TICKS_AT_EPOCH;
return tick;
}
This works fine when I run this code as a Java file. It encrypts the data as expected. But, when I use this code in the android application, it gives below error.
java.lang.RuntimeException: error:03000068:bignum routines:OPENSSL_internal:CALLED_WITH_EVEN_MODULUS
at com.android.org.conscrypt.NativeCrypto.RSA_public_encrypt(Native Method)
at com.android.org.conscrypt.OpenSSLCipherRSA$DirectRSA.doCryptoOperation(OpenSSLCipherRSA.java:371)
at com.android.org.conscrypt.OpenSSLCipherRSA.engineDoFinal(OpenSSLCipherRSA.java:292)
at javax.crypto.Cipher.doFinal(Cipher.java:1741)
Equivalent C# code is as below
public string GenerateToken()
{
var completeToken = string.Format("{0}:{1}", _dataToEncrypt, DateTime.UtcNow.Ticks);
var encryptedToken = EncryptionHelper.Encrypt(_publicKey, completeToken);
var token = Convert.ToBase64String(encryptedToken);
return token;
}
public static byte[] Encrypt(string publicKey, string data)
{
var cspParams = new CspParameters { ProviderType = 1 };
var rsaProvider = new RSACryptoServiceProvider(cspParams);
rsaProvider.ImportCspBlob(Convert.FromBase64String(publicKey));
var plainBytes = Encoding.UTF8.GetBytes(data);
var encryptedBytes = rsaProvider.Encrypt(plainBytes, false);
return encryptedBytes;
}
Ref link Translating C# RSACryptoServiceProvider into JAVA Code