I'm trying to generate a signature using RSA 256 but I've got a different result between JavaScript and PHP.
My JavaScript code:
let private_key_path = Helpers.publicPath('key/API_Portal.pem');
// password .pem file
let password = 'mandiri123';
let data = client_id + "|" + timestamp;
// load private key file
let rsa_algorithm = jwa('RS256');
let privateKey = fs.readFileSync(private_key_path);
let signature = rsa_algorithm.sign(data, {'key': privateKey, 'passphrase': password});
return signature;
Output:
tCB6v9_UnUTNpkeTZwgjn-iepO4XGwhZ72Q7LONarc-wT8pC18gyd46GYT8I1dLwVymPRDOzWwA9XXELRncG-CmYXlrutJssAUKmDv3hMRedbDu7-60OU9haSaBskedPoqlL76CigQXJ8ZX2_gnf8YG2-wALJfD1VquQWinmSUsMAD2bMB_EgDmSlOLrr_5BSKO2Pzq3XpJxcriptl-l6s7SsR_K6Gb1KYyhxmOAm41nKG9i-kUhvyDaZzTQ9Hw1_vqPOJN8gNhj6lnHimwizIOENsOtkIKhwa5QjL1Oa3PtnrMhCaQ9fWsUG83-rPOkbOulB5o12qWTxmeSJVsW8w
My PHP code:
// Specify private key location, passphrase, data, and hash algorithm
$private_key_path = public_path('key\API_Portal.pem');
// Password .pem file
$password = 'mandiri123';
$data = $this->clientId . '|' . "2020-11-19T11:35:57.190T+0700";
$rsa_algorithm = OPENSSL_ALGO_SHA256;
// Load private key file
$fp = fopen($private_key_path, 'r');
$privatekey_file = fread($fp, 8192);
fclose($fp);
$privatekey = openssl_pkey_get_private($privatekey_file, $password);
// return $privatekey_file;
// Sign data
openssl_sign($data, $signature, $privatekey, $rsa_algorithm);
$result = base64_encode($signature);
return $result;
Output:
tCB6v9/UnUTNpkeTZwgjn+iepO4XGwhZ72Q7LONarc+wT8pC18gyd46GYT8I1dLwVymPRDOzWwA9XXELRncG+CmYXlrutJssAUKmDv3hMRedbDu7+60OU9haSaBskedPoqlL76CigQXJ8ZX2/gnf8YG2+wALJfD1VquQWinmSUsMAD2bMB/EgDmSlOLrr/5BSKO2Pzq3XpJxcriptl+l6s7SsR/K6Gb1KYyhxmOAm41nKG9i+kUhvyDaZzTQ9Hw1/vqPOJN8gNhj6lnHimwizIOENsOtkIKhwa5QjL1Oa3PtnrMhCaQ9fWsUG83+rPOkbOulB5o12qWTxmeSJVsW8w==
The result in PHP is correct, why is there a difference between the two?
According to section 3.3 of JWA specification:
The RSA SHA-256 digital signature is generated as follows:
- Generate a digital signature of the bytes of the ASCII representation of the JWS Secured Input using RSASSA-PKCS1-V1_5-SIGN and the SHA-256 hash function with the desired private key. The output will be a byte array.
- Base64url encode the resulting byte array.
Note that base64url encoding is different from the standard base64 encoding used by PHP. The +
and /
are replaced with -
and _
. A simple string substitution is all that's needed to make them the same.