Hello,
We are currently porting a native Android app to flutter and need RSA verification for it. Unfortunately, the verification with pointycastle does not work when we use our test cases. The signature is created on a spring boot backend based on java. Can you help us further?
pointycastle version 3.7.3
Android Implementation
private fun verifySignatue(signaturePublicKey: String, signaturePayload: String, base64CipheredPayload: String): Boolean {
val signature: Signature = Signature.getInstance("SHA384withRSA")
val publicKey = KeyFactory.getInstance("RSA")
.generatePublic(X509EncodedKeySpec(decodeBase64(signaturePublicKey)))
signature.initVerify(publicKey)
signature.update(base64CipheredPayload.toByteArray(StandardCharsets.UTF_8))
return if (signature.verify(decodeBase64(signaturePayload))) {
true
} else {
throw BarcodeException("signature check failed")
}
}
Flutter
const publicKey = 'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAtDTEndUdEOh7SQUioTdF5oJWJBFl/x+S5K8lICMABWoHt7ityLM16GHW+veR16frgJNVPy9V9QGzvGoTQNro0T3f/mMn3Rj1EvlT0Of7QLmniSowXQYtjFhTxPpuSlGG4X4vtFrEQWyq+sQLIwy9Q6O7wBvVpK9NJ+X4s2X909KW52XMCy2q3nlT7xJRK0m9b9OH2YWORztEBBX2rx8CD5xJnx3VC8Mcc4wnlruHl21zRyjvUF7Fk7z1c6pb71juCxt2QmaM2ulKQI2UiZN/vHFIeg3V6SKkOH+qhwQbDuiFO6pAQTCsbuDYKGxltSk8qaqU8LfijVFczAZLPbb02cktmhyUlqbHoeRcl4/nSutvb+n6ite259mcSeoz+FHRXqolCiviQAAnpfF/sPfNKpHH7kaXrbjQA5Ak47YjCcqax3sfduh1CYDrm3mlEmgtdzEIpO9rWvQmpAwuBKleq0fiC/PxPEPRjDprbi84GyY/8nh9BbLn+ffCkBoZGJexAgMBAAE=';
const signature = 'P1EopKclBjgn37mL3EhjWr8tyVvMw1cxJAys533HcNyxWW0q7sEd5HWXoJ1pSIK9cXlCVzAN7wK+VsO2qCCvEeDDbpO/PPtYE7jrB/Sm8XjnL6BBvt4rMcLGVNBamRgLjbQ0Qa466KgOfNdpcFDu04Vxk8cknRYXsWmEkh++QgNCdtIvhu3k/rFyD6iJjj/nqs3/1JMh4utbiOcCXZylPDVv7WJBTYYmKlTT92aq3H42o5EImclA4u7KEjUff++yiPgZ++d1E/gFs2omp99fpoSWVBGgs5todUFS/6qvLkPzPnvUL5FOUm5CClbJWVgSgEaRxZ4ctg790HQCO1OFk81USacQPfIWqHvOpayORM1G121nEO31fvTJYf7FTL1EfIGHNnT8AcFbS2Z/crxbnp00xIzGF9uRQ8xftGvdb1lQH7VXa9ZxA6GtFiXFdiT81MLJdcyd9VYpYNzyE1Z3JoeAW88q9YmFRZj9gCVu2EbirphvFXe114otZQUnqCeg';
const payload = 'C7KDZkNbemqgs7d4JXlAYZQx11+mAB53QkJogF6/FfyXjspoykb6gf3yTm4tPaoaDTTvFrEJGETuCkeXLaLPz2OtKlOdSoZaI/RpGqCsRx1YftWzLrGTFPtXno0tVsr499vCv971wO/cOPJxCl460g8v64vj6WGFL5vHhFrlqzRS3p/pZ/APIAMNyZjwqpVfPru61shXpI8PIm66tOy2LhzfFOhg50dSHuyYG8M5kVf+fiO/QFLdE3t7KsCl/tvQXHlNAkTaOkPx8fH9ZMYdqk9SxF+7hJrxBq1lXx/YO427G49uxlkf9NPQk3nJAv0MtVfZprr6WZ+FVMDsk3y2bdVoFg4DUFLE/x3tCFs3gAyZBFYuJzne7SAtYTQUEUnoiD6RPU6xSvFfnuyzO7v5KevJZy0dxfKoIccxsuo08JlTQ/Xhdg1rcsTIUoJXKSNzKscEnPygRLBz2iR00xpSMgCfTYOp1PdebAfSYtJAQeMJ2Vppkfpgjey+xcXaUF8q6/vH+CyddUra48bkVVXrcu2ssRW9kv5VdzIhIK85QGdi59nCDFyx4tbOVjKwM0ztn5s347fJ+8/DLUWNBhy5X292rtibz+nR8rDoGsJVAO2eP6BUIKRA6zSYpKDYFC2cT+xERGb609DbVEm6fPdYmVwSdm4BjCP/bMY4Cy924TWcPcY9Z7NeeIiPdIGiJBLcNv4ARJQZjVzUFNJgxBDlua4RxrR2mDeJLQ==';
class RsaVerifier {
bool verifyRsaSignature({
String publicKeyBase64 = publicKey,
String signatureBase64 = signature,
String payloadBase64 = payload,
}) {
final signature = base64Decode(signatureBase64);
final publicKey = base64Decode(publicKeyBase64);
final signedData = payloadBase64.convertToUint8List();
final rsaSignature = RSASignature(signature);
final rsaPublicKey = PublicKeyParameter<RSAPublicKey>(
_rsaPublicKeyFromDERBytes(publicKey),
);
// final verifier = RSASigner(SHA384Digest(), '0609608648016503040202');
final verifier = Signer('SHA-384/RSA')
..init(
false, // false means verify
rsaPublicKey,
);
try {
return verifier.verifySignature(signedData, rsaSignature);
} catch (error, stackTrace) {
throw SignatureVerificationFailedException(
error,
stackTrace: stackTrace,
);
}
}
RSAPublicKey _rsaPublicKeyFromDERBytes(Uint8List bytes) {
final asn1Parser = ASN1Parser(bytes);
final topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
ASN1Sequence publicKeySeq;
if (topLevelSeq.elements![1].runtimeType == ASN1BitString) {
final publicKeyBitString = topLevelSeq.elements![1] as ASN1BitString;
final publicKeyAsn =
ASN1Parser(publicKeyBitString.stringValues as Uint8List?);
publicKeySeq = publicKeyAsn.nextObject() as ASN1Sequence;
} else {
publicKeySeq = topLevelSeq;
}
final modulus = publicKeySeq.elements![0] as ASN1Integer;
final exponent = publicKeySeq.elements![1] as ASN1Integer;
final rsaPublicKey = RSAPublicKey(modulus.integer!, exponent.integer!);
return rsaPublicKey;
}
}
extension on String {
Uint8List convertToUint8List() {
return Uint8List.fromList(utf8.encode(this));
}
}
Hello, We are currently porting a native Android app to flutter and need RSA verification for it. Unfortunately, the verification with pointycastle does not work when we use our test cases. The signature is created on a spring boot backend based on java. Can you help us further?
pointycastle version 3.7.3
Android Implementation
Flutter