Я пытаюсь портировать наше мобильное приложение для Android на Flutter. Это было написано на Java. Однако есть часть, где мне нужно зашифровать учетные данные для входа в систему и данные карты с помощью шифрования RSA, прежде чем отправлять на сервер, который я не смог получить.
Я пробовал несколько пакетов флаттера, которые не работают. По словам разработчика Java, существует открытый ключ в кодировке base64, который необходимо использовать при шифровании пароля.
Вот код Java
public static String Encrypt(String plaintext, String publicKey ) throws Exception {
try
{
if(StringUtils.isEmpty(plaintext)) return "";
byte[] modulusBytes = Base64.decode(publicKey.getBytes("UTF-8"),Base64.DEFAULT);
byte[] exponentBytes = Base64.decode("AQAB".getBytes("UTF-8"),Base64.DEFAULT);
BigInteger modulus = new BigInteger(1, modulusBytes );
BigInteger exponent = new BigInteger(1, exponentBytes);
RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(rsaPubKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] plainBytes = new String(plaintext).getBytes("UTF-8");
byte[] cipherData = cipher.doFinal( plainBytes );
String outputEncrypted = Base64.encodeToString(cipherData,Base64.NO_WRAP);
return outputEncrypted;
}catch (Exception ex)
{
Log.i("Exception", ex.getMessage());
throw ex;
}
}
Буду признателен, если смогу помочь с преобразованием этого в дротик, чтобы использовать его в коде флаттера.
UPDATE
Я попытался использовать шифрование @Richard Heap pointycastle, которое, кажется, работает нормально, но сервер не смог расшифровать строку. Исключение
Interop+AppleCrypto+AppleCFErrorCryptographicException: The operation couldn’t be completed. (OSStatus error -2147415994 - CSSMERR_CSP_INVALID_DATA)
at Interop.AppleCrypto.ExecuteTransform(SecKeyTransform transform)
at Interop.AppleCrypto.RsaDecrypt(SafeSecKeyRefHandle privateKey, Byte[] data, RSAEncryptionPadding padding)
at System.Security.Cryptography.RSAImplementation.RSASecurityTransforms.Decrypt(Byte[] data, RSAEncryptionPadding padding)
at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: The parameter is incorrect
at Internal.NativeCrypto.CapiHelper.DecryptKey(SafeKeyHandle safeKeyHandle, Byte[] encryptedData, Int32 encryptedDataLength, Boolean fOAEP, Byte[]& decryptedData)
at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP
Метод расшифровки на сервере написан с помощью C #
ОБНОВЛЕНИЕ 2
Наконец-то я начал работать после нескольких часов поиска в Google. Я обнаружил эту проблему github на PointyCastle и решение от duncanhoggan. Оказалось, что мне просто нужно использовать PKCS1Encoding.
var pubKey = RSAPublicKey(modulus, exponent);
var cipher = PKCS1Encoding(RSAEngine());
cipher.init(true, PublicKeyParameter<RSAPublicKey>(pubKey));
Uint8List output = cipher.process(utf8.encode(text));
var base64EncodedText = base64Encode(output);
return base64EncodedText;
@ Ричард Хип, спасибо за помощь.