我想在android中使用公钥和私钥实现RSA加密。我所做的实现如下。
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;
}
当我将此代码作为 Java 文件运行时,效果很好。它按预期加密数据。但是,当我在 android 应用程序中使用此代码时,它会出现以下错误。
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)
等效的C#代码如下
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;
}
参考链接将 C# RSACryptoServiceProvider 转换为 JAVA 代码 https://stackoverflow.com/questions/18089923/translating-c-sharp-rsacryptoserviceprovider-into-java-code