0

I am trying to sign a piece of text using a private key using SwiftyRSA, which I do successfully. Then send the signature to the python server which holds the public key for verification. the But I keep receiving the InvalidSignature exception.

I have tried different hashing algorithms, bit sizes, but still the same InvalidSignature exception. I am sure that the key and signature are related b/c they are generated at the same time!

My issue is not with the libraries themselves--which I think are functioning properly. I think it has to do with a padding discrepancy between the two libraries. Cryptography is using PSS, while I cant find the padding/salt that SwiftyRSA uses.

Key Verification Script


@app.route('/', methods=['POST'])
def verify():
    record = json.loads(request.data)
    signature = record['sig']
    public_key = record['public_key']
    hash_local_token = record['hash_local_token']
    input_string = record['input_string']


    verification_response = auth.verify_signature(signature=signature, pub_key=public_key, input_string=input_string)
    print(verification_response)
    return jsonify({"Verification": verification_response})


def verify_signature(signature, pub_key, input_string):
    # Load the public key
    # Url Safe Base64 Decoding

    derdata = base64.b64decode(pub_key)
    public_key = load_der_public_key(derdata, default_backend())
    signature_decoded = base64.urlsafe_b64decode(signature)

    # Perform the verification.
    try:
        public_key.verify(
            signature_decoded,
            str.encode(input_string),
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=padding.PSS.MAX_LENGTH,
            ),
            hashes.SHA256(),
        )
        return "SUCCESS: Signature Verified!"

    except cryptography.exceptions.InvalidSignature as e:
        return 'FAILED: Payload and/or signature files failed verification'

Key Generation Script

 func moreTesting() {
        
        do {
            let keyPair = try SwiftyRSA.generateRSAKeyPair(sizeInBits: 4096)
            let privateKey = keyPair.privateKey
            let publicKey = keyPair.publicKey
        
            
            let inputString = "test_string"
            let clear = try ClearMessage(string: inputString, using: .utf8)
            let signature = try clear.signed(with: privateKey, digestType: .sha256)
            let base64Signature = signature.base64String
       
            
            let parameters: [String: String] = [
                "sig": base64Signature,
                "input_string": inputString,
                "public_key": try publicKey.base64String()
            ]
            
            AF.request("http://127.0.0.1:5000/", method: .post, parameters: parameters, encoder: JSONParameterEncoder.default).responseJSON { response in
                debugPrint(response)
            }

        }
        
        catch {
            print(Error.self)
        }
        
    }
yen936
  • 53
  • 7

1 Answers1

1

It appears that SwiftyRSA's signing APIs use only PKCS1 and not PSS. See: https://github.com/TakeScoop/SwiftyRSA/blob/master/Source/Signature.swift#L20-L27

So to resolve this you'll want to switch your padding from PSS to PKCS1v15 on the Python side.

Paul Kehrer
  • 13,466
  • 4
  • 40
  • 57