1

I am currently working on sending a request to Snowflake using Key Pair Authentication. They have provided me with a private key and a public key, and for testing purposes, I have hardcoded them as follows:

String privateKey = '-----BEGIN PRIVATE KEY-----\n' +
        'MI56GHYFDgkqhkiG9w0BAQEFAASCBKkwgDFDFQC/38qQEqZcSO2F\n' +
        'GwgOTsxJQ4bELFvfq7qoDaMKtZBHDh42dGZro2NrJ+d/deUg+9hH0qwnidke9PEx\n' +
        .....
'-----END PRIVATE KEY-----';

privateKey  = privateKey .replace('-----BEGIN PRIVATE KEY-----','');
privateKey = privateKey .replace('-----END PRIVATE KEY-----','');
privateKey = privateKey .replace('\n','');

String publicKey = '-----BEGIN PUBLIC KEY-----\n' +
        'MIEFHYuyuzGkiG9w0BAQEFAAOCAQ8AMIIBCgKDDFGHH34KkBKmXEjthRsIDk7M\n' +
        'SUOGxCxb36uAAAtyuw4eNnRma6Njayfnf3XlIPvYRdfGT65vTxMY1wwVO6\n' +
        ......
        '-----END PUBLIC KEY-----';

publicKey = publicKey .replace('-----BEGIN PUBLIC KEY-----','');
publicKey = publicKey .replace('-----END PUBLIC KEY-----','');
publicKey = publicKey .replace('\n','');
String encodedPublicKey = EncodingUtil.base64Encode(Blob.valueOf(publicKey));

After that, I created the header:

JSONGenerator jsonHeader = JSON.createGenerator(false);
jsonHeader.writeStartObject();
jsonHeader.writeStringField('alg', 'RS256');
jsonHeader.writeStringField('typ', 'JWT');
jsonHeader.writeEndObject();
String encodedHeader = EncodingUtil.base64Encode(Blob.valueOf(jsonHeader.getAsString()));

And the payload:

JSONGenerator jsonBody = JSON.createGenerator(false);
jsonBody.writeStartObject();
jsonBody.writeStringField('iss', accountId+'.'+userId+'.SHA256:'+encodedPublicKey);
jsonBody.writeStringField('sub', accountId+'.'+userId);
jsonBody.writeNumberField('iat', Datetime.now().getTime());
jsonBody.writeNumberField('exp', Datetime.now().addMinutes(3).getTime());
jsonBody.writeEndObject();
String encodedBody = EncodingUtil.base64Encode(Blob.valueOf(jsonBody.getAsString()));

Finally, I attempted to generate the JWT request:

String jwtRequest = encodedHeader + '.' + encodedBody;
Blob key = EncodingUtil.base64Decode(privateKey);
Blob signature = Crypto.generateMac('HmacSHA256', Blob.valueOf(jwtRequest), key);
String signatureEncoded = EncodingUtil.base64Encode(signature);
signatureEncoded = signatureEncoded.replace('+', '-');
signatureEncoded=signatureEncoded.replace('/', '_');
signatureEncoded=signatureEncoded.substringBefore('=');

String signedJwtRequest = jwtRequest + '.' + signatureEncoded;

However, I encountered the following issue when tried to copy the token into postman

{
    "code": "390144",
    "message": "JWT token is invalid. {0}"
}

I have requested the external source to generate a valid JWT using the same variables (they did it with snowSQL), and the token they provided works. I dont sure if its need to be the same length of chars everytime but the generated token has 616 characters, while the one I generated is 1027 characters.

I have followed the steps outlined in the Snowflake documentation here, but something seems to be amiss.

As I am relatively new to integrating with JWT, any assistance with an explanation would be highly appreciated.

Many thanks!!!

3

0

You must log in to answer this question.

Browse other questions tagged .