The input for String key
should be the PKCS#8 formatted Private key. If you follow the instructions on the blog you linked to, use the string of characters between the outputted -----BEGIN PRIVATE KEY-----
and -----END PRIVATE KEY-----
.
Short Version of instructions -
- Generate a private / public key pair (CA or Self signed is up to you), formatted RSA / SHA1, in .PEM format.
- Convert .pem format private key to PKCS#8 format
openssl pkcs8 -topk8 -nocrypt -in myPrivateKey.pem -outform PEM
- Take terminal output between
-----BEGIN PRIVATE KEY-----
and -----END PRIVATE KEY-----
and use as String key = '';
- Make sure you do not have any line-breaks or carriage returns in the string, as is usually output to the terminal. This will make your key not work as Apex does not support multi-line strings.
DISCLAIMER: I'm not a crypto expert, this is an informed guess using the linked references.
According to the Wikipedia article on JSON Web Tokens,
Typical cryptographic algorithms used [for signatures] are HMAC with SHA-256 (HS256) and RSA signature with SHA-256 (RS256)
Sp "HS256" refers to an HMAC, which Wikipedia defines as a "Hash-based message authentication code", where as "RS256" is an "RSA Signature" (not an HMAC), but both are computed using the same hash type (SHA-256).
The answer you link to generated the signature using Crypto.generateMAC()
as follows:
String algorithmName = 'HmacSHA256';
Blob hmacData = Crypto.generateMac(algorithmName, Blob.valueOf(saltValue), Blob.valueOf(secretKeyValue));
According to the documentation for Crypto.generateMAC().
The valid values for algorithmName are:
- hmacMD5
- hmacSHA1
- hmacSHA256
- hmacSHA512
So no "RS256" in the list, but the method is named CreateMAC()
, and from the above we believe the RS256 is a signature, not an HMAC. Looking at the Crypto library we see:
sign(algorithmName, input, privateKey)
Computes a unique digital signature for the input string, using the specified algorithm and the supplied private key.
Further, RSA-SHA256
is a valid value for algorithmName
. So I suspect that you need something like:
string input="..."; // what you want to sign
string privateKey="..."; // your private key
blob rs256sig = Crypto.sign(
'RSA-SHA256',
Blob.valueOf(input),
Blob.valueOf(privateKey));
Update: Note that Crypto.sign()
returns a blob
, which is binary data. If you need the signature in a text format, you can encode it as Base64 or Hex using EncodingUtil
. I believe that hex encoding is common for signatures, e.g.,
string hexSignature = EncodingUtil.convertToHex(rs256sig);
Best Answer
You must follow the Following link it will be helpful for you to understand the Signature varification in Salesforce Apex. For
SHA1
you can use the below code snippet:use this str if you want signature in url encode if you want it in
base64encode
form only, then use the below code in place of str:For
HMACSHA256
you can use the below code snippet:Use the str/macUrl where you want to use Signature may be it in the header if you use the
POST
method. For Sha-1 signature in APEX You can follow the below three links: http://www.tgerm.com/2012/07/sha-1-apex-rackspace-salesforce.html AND http://blog.jeffdouglas.com/2010/07/06/using-rsa-sha1-with-salesforce-crypto-class/ and http://wiki.developerforce.com/page/Apex_Crypto_Class