Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSA Verification failed with SHA-384/RSA #210

Open
SebastianKlaiber opened this issue Oct 24, 2023 · 0 comments
Open

RSA Verification failed with SHA-384/RSA #210

SebastianKlaiber opened this issue Oct 24, 2023 · 0 comments

Comments

@SebastianKlaiber
Copy link

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));
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant