How to get R and S values from ECDSA signature using PHP - php

I am working on Signature of data using ECDSA from Starkbank library and I can get the base64 format of the signature value MEUCIALlD6Xsd0Xdj7XTrD2gP4Q3PlssTxLOCUi6R8FbXMlbAiEAmW8HLiBnhaBBPzIL64FGzFYzUwF1HfX+a8ep5/NpI0k= and the Der value is 0E ���wEݏ�Ӭ=�?�7>[,O� H�G�[\�[!�o. g��A?2�F�V3Su��kǩ��i#I
but I want to know the R and S values with the length as well, how can I achieve it?
my PHP code is:
<?php
require_once "src/ellipticcurve.php";
#privateKey from PEM string
$privateKey = EllipticCurve\PrivateKey::fromPem("
-----BEGIN EC PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgPUAdAJuELXoxEumrKUPd
yHLP9bITTV+yOSw5q1H8W/2hRANCAASW6MSUA/wJRcj0AljN0tnpMBp5ISqTp8j/
rY7C2BXCXyy03V/lP7jn0LSgJvykVyNRPXfA4zjpFRaOUNWUBNuU
-----END EC PRIVATE KEY-----
");
$message = "j4+wDOaRLRQn7oweoCbob1WDaqPRCTHzonn08b+dJr0";
$signature = EllipticCurve\Ecdsa::sign($message, $privateKey);
# Generate Signature in base64. This result can be sent to Stark Bank in header as Digital-Signature parameter
$base64 = $signature->toBase64();
$der = $signature->toDer();
echo "\n" . $der;
echo "\n" . $base64;
$publicKeyPem = EllipticCurve\Utils\File::read("publicKey.pem");
$publicKey = EllipticCurve\PublicKey::fromPem($publicKeyPem);
# To double check if message matches the signature
//$publicKey = $privateKey->publicKey();
echo "\n" . EllipticCurve\Ecdsa::verify($message, $signature, $publicKey);
?>
the ECDSA config which I am working on:
digest_alg = "sha256",
private_key_bits = 2048,
private_key_type = OPENSSL_KEYTYPE_EC,
curve_name = secp256k1,

You Can Use SOP/ASN1 To get the Sequence from DER.
Try https://lapo.it/asn1js to find the Positions from R and S. Use bin2hex($signature->toDer()) to get Hex-Encoded ASN.1
It depends on the Type of your $signature->toDer().
Maybe your Hexstring is already Sequence, then following two ANS.1-Integers (R/S).
Then use for e.g.
$seq = \Sop\ASN1\Type\UnspecifiedType::fromDER($signature->toDer())->asSequence();
$seq->at(0)->asInteger()...
$seq->at(1)->asInteger()...

Related

phpseclib 2.0 generates different signature than any other library with same parameters

Introduction
Hello, when signing a simple string Hello World! I get a signature that is different from any other library I'm using. I already double checked padding, algorithm, key pair, hash and input text.
Code
<?php
/*
$config = array(
"digest_alg" => "sha256",
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$resource = openssl_pkey_new ($config);
// Extract the private key from $res to $privKey
openssl_pkey_export($resource, $privKey);
// Extract the public key from $res to $pubKey
$pubKey = openssl_pkey_get_details($resource);
$pubKey = $pubKey["key"];
echo var_dump($privKey) . "\n" . $pubKey;
*/
//require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/autoload.php';
use phpseclib\Crypt\RSA;
$privatekey = "-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----
";
$publicKey = "-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAn4CD0nFHCeM3DQkCWfXu
qRVlX4rbqEk43lMgEns4DnTldrSl1oaD9YOnwGktk7MaCf80AAZv2O4a9LIfvMxB
f+LshgqTOAgvr1qy9bIkn0o/BBNYbwOTCEnbvSha6uHlexpr31aRvzj8km4uzeBu
sUyJaXgF8ZMcp0UmThhdYlHhWP1EuajkbXS8/zlD2F4TVaiPgvupIoWC62PMe5Qv
NWjrxOYSNwiV29QVxnHt8xm5Vx1JET1A4uUCVnOUQ5L+zBv+BYhCHr03j6aq+Z1a
KHpEsYtCQPRCJJ/+r24+yd8tMJ2u63feVCcSOfuZTYG8Qlr5wZICuGimneeKWpau
OCqmb7osVDZfY7e2xSxnbjabtVqni43NWB0CcXwQ4fIbHX0/JdWmLbupIhTBJDzO
6CCpyE506UZJGZOu7t16FBwGVLh3jE1nLxwIbswv7oiN9fFBP+2eebvyuEvkSwYe
vGc16Mh4qfnHARwhiG0aflrUbf8hls2NrvCRTm7mRIjCBZe8rM7VWyZbUaA8DI8N
E3/PnwjvRWLdmEqM2ShVBuDnDpeDx46x58B1HZqeGx7HwfL/x/fSRG3uvBAG/lqK
mq3o1E1gmauHm6jcnHOUftlt6nv0xfqboScJYVgPkNT0l3rzKUtNwI3Bh0X/Yhy4
ikEl9DTSFOhWa9ReUwYOqVMCAwEAAQ==
-----END PUBLIC KEY-----
";
$rsa = new RSA();
$rsa->loadKey($privatekey);
$rsa->loadKey($publicKey);
$rsa->setHash('sha256');
$rsa->setMGFHash('sha256'); // Added to see if it made a difference. It made no difference
//$rsa->setSaltLength($sLen)
$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1); // Added to see if it made a difference. It made no difference
$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
$plaintext = 'Hello World!';
$signature = $rsa->sign($plaintext);
$rsa->verify($plaintext, $signature);
echo base64_encode($signature);
?>
Output vs expected output
Output: Zhy04W5K+Xjhd3isDi3rlqpUgGAmcTKpW7HEPQiG8eIaxqPVqOilw60zOcS1GDuPn2b5Z1UWyvBNbw3r5fK9JSxAXCGFtbe/Fd8nGtAsCe9RW9oQ14OCwpuqWFJwADdax0GAh0KC/2JpmHYu+GG8IfESgG4NPxwe36r861jdIW9icsmcRUQOpfCkIsKClbwBhS74oIQAmbxMl23hNqzue6I7+onlZxNqnVH1XLPsMZghx1CkkpVGnSm6bHmiz01AFTF9U5oHto5MLLy1UMIhFDOFOxNHwC4ISK8kC8vnfUkm3nM3GQMD+yvDYPKLse0dYBPUcmFwiErSOkG8guA5IG4nWCkM2V5GpBHPwsGFpckjKOUvsuq+8g3ILqkW5IZSBUDaTSsHUd0CxD05DzZOGOBQ5Lhm3vMm2kbO5uwlTYbZX5deLJLOJivCip56CGX4GpAfT/VRctLyl5NL2CwVE3zUKMTnOj/NLoU7Liqw4WaYKekB2vTCUWcse8mdX1ZiUNxW3EHiXiEGB1yzVxPE0QaLdcfK3pyVVpkd5cxHOdXI5Zg/5RkADYiueyO/1oIObzHPEcAvdoj5fxW5XKnFPux6KzjWdqnqVyZXKNSZquJodn0408n2NGLrEukOVlMaixnNgvj7lmHtz/UlN0FNRzCHwVDl4q3uOiVPfRmj+28=
Expected output: J8iGPq9MWUHnzHYJqNE3y/o41uZXTdr+JGOl7YN06qIv+vbylgL367Y8B0jA/LYPcPIJDpUs991DdHEgFAE/+JkVYcrKZpmGXSFvR3RWaTe3DQZMoeD07iaOElJXVn6XBWbU77hCDUMkWXwWHbH9Ybs9BDyq8VHCrhHXgo4zyRNHB+Hb4LLVPyFCv+nQ8d6wCbY14ecyMiL5xS27g78aAg+87uTaq/naLPiSUftKiq0/ih9/Jk6IxrSLsfF4XRD2uAe5jruUMe+wZmzzYeS1syl1nto2FX/28k/z2c8Bt1Rr7nl4E6uiEKO2jYknBkwvJ2MVmbiANpeal534GRvBWaHvTGU/kZa4hEjDkRbZJ/byvLIOMrafoCQfmHYVBLS1OkVEraa34LIqla38VAV7QQGtUrq4ehYsJ16daacysCkJcuvyYz0qNoSvBV9Knh727eEbkLHrYkjf7LjYvWkVXt82AwdohzlnbQb/Ge1BhR+tV0jmC5ztpHE6xzRqkjuNU3mYKjE/Jp+udKokNXcPZcbCrFhA8MY6ay/ldy8ySYl3vTdzE0d8FzIVn/z8fBJme/nCDLeP8/bRja+dpwKwWO0c9k/cyKs0M0YEyZ/PF/CYm/sPBMZHFY4cJacVqrkbnFgEWSAnEJ8SLCqLNXKQR/4hOhlC9sF3asMCkGszrgc=
Additional details
I'm sure I'm using:
RSA
SHA256
PKCS1
Hello World! as input text
You can check using openssl or 8gwifi RSA Signature/Generation & Validation (make sure you paste the keys provided and change the signature algorithm to SHA256withRSA)
Found the problem. When loading the keys you can't load both. You need to load the one you need, do whatever operation you need and then load the other one for the next operation.

php signature output in a copy'able string

I need to copy paste the signature of a specific input in PHP, there are no errors but the resulting signature is a bunch of symbols and not alphanumeric characters, I highly assume its because I am missing some encoding somewhere.
This is my code:
<?php
$unformatted_pub= "-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs9D/xyfj7Ocgzaytkqsp
f/ABE5csbukSkmkRi9VzuxZZ9v95WJmxldH1QTIKEjAjeGuFoYY+WhqsTQYG3RuM
cZ3e0Vp26Qkkxyu2MU4fuu/ht1AYiq6SMstnS49l5D8ptjh1ZUyWjFHr+sMyHSi/
jiLUtbIK4lzpZHjMJ4g8JknKLhINLeMscRwXFEvfgSPO9AJ1hAFjuWT3UbCOS9s1
nq6daE6TexCOlXbm4rPeRHxIuZJxawPGkQAx/X9sk5mww2kJk1nbmBSll/B2qp7k
jQmXz3J/g+VwQnCIB5XtZ4bOSEVh7GBwYCkmu8PZthZVMiBlHBICTYzGyyWt2djP
lS+jen0BAIrxV3mshB4ErZsRToNCFRzGlRg1opQCJngw1NProlcGMzh1LC5C7Han
awoFUwWaGypAx2XL04WsMo4MJYgKDVN545f/SaXXVG+fTYjWX4I6GyGlqLRjfijY
SGdupIlFUdHPPKNVr1A2JZNYwBtBepvv5DEmD4+yy3gf6hwL4IYZOfUZrpl4YxoH
uZsD0Ly/2ayQBujWgmTdgoPrYB7GKwjc/jgPKvJTU965FOmKd2ujeTfed8HAky7G
DL1zrr0URMC4IZ6CtLF9BEazwzx5CrnOLZ4b2fcxgeX7C36GvNzKgD2PIhYJid10
rb/7Al/a/mWeyZGUxffhkB0CAwEAAQ==
-----END PUBLIC KEY-----";
$unformatted_priv = "-----BEGIN PRIVATE KEY-----
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
OoyA4sufCzG5Wgy5iBquldUSELkxXEM=
-----END PRIVATE KEY-----";
$data = '1234';
// compute signature
openssl_sign($data, $signature, $unformatted_priv);
echo $signature;
?>
And this is the result:
���3��TQW<�^�T�Kd�i�hF�X�:0��d�GޱE�)�z9H������ө%CO��H�m˻J#���'6�>�Q�vn�r�&��絛k�=�X��_�ꗼ������1oK�3�1���&�EI��=�����}򤡖]Qo��u 4�'�\� �l��u��/������q�%���2�����)��3+����`��q҃|I�Of֯\�|e�h��u�i�"[Mjtc���"�^���j"s8��'���Y���upW9���1�#��CB�͇�f�ߩ�Hn�N�KF�#,e�݇��7�� �� aIB?.v#���Q�j>z4� ���/s����͇����uߌ,�u��!ᄃ���+"� uO �{��O3]���h}�- �|�s����;F;�ɣj�x�O=�aw$�Jz7� (ѬJbN�T�?(<��}X%��������!y\V�5u���_C�K��s��<}�M|#w��?�mey�
Lastly, I tried to verify the signature which returns True, so there are no errors, I just want the signature in a format where I can copy and paste it.
Any and all help is greatly appreciated.
echo base64_encode($signature);
As PHP docs example suggests the best way is to save signature to a file instead of copying it.
//create signature
openssl_sign($data, $signature, $private_key_pem);
//save for later
file_put_contents('private_key.pem', $private_key_pem);
file_put_contents('public_key.pem', $public_key_pem);
file_put_contents('signature.dat', $signature);
//verify signature
$r = openssl_verify($data, $signature, $public_key_pem);
var_dump($r);

Cannot get signed url to work with gcloud storage

Cannot get signed url to work with gcloud storage.
I know there is probably something simple that's missing here but I can't find it.
Trying to create a signed url to a file in a gcloud bucket following the directions here https://cloud.google.com/storage/docs/access-control/create-signed-urls-program
Created a servive account and downloaded the pk12 and converted p12 to pem to get the key.
Here is code:
$pkeyid = "-----BEGIN RSA PRIVATE KEY-----
[removed actual key]
-----END RSA PRIVATE KEY-----";
$secret = "notasecret";
$expires = time()+86400;
$http_method = "GET";
$bucketName = "mybucketname";
$stringtosign = "GET\n
\n
text/plain\n
".$expires."\n
\n
\n
\n
".$bucketName ."/mymediafile.mp4";
openssl_sign($stringtosign, $signature, $pkeyid);
$emailid="serviceaccount#[project].iam.gserviceaccount.com";
$signature = urlencode(base64_encode($signature));
$gcloudloc = "https://storage.googleapis.com/".$bucketName ."/mymediafile.mp4?GoogleAccessId=".$emailid."&Expires=".$expires."&Signature=".$signature;
I get what looks like a valid signiture, but when I try to use the full url I get
The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.
I had two issues:
Pasting in the Private Key.
Missing some parameters in the openssl_sign
Also my $stringtosign seems to mess it up. Changing to all one line fixed that part.
I found this "Google Cloud Storage Signed Url for media" and was able to use the function (below) from hdezela to get it working!
function storageURL($bucket,$archivo) {
$expires = time()+60;
$to_sign = ("GET\n\n\n".$expires."\n/".$bucket.'/'.$archivo);
$fp = fopen('/path/to/google.pem', 'r');
$priv_key = fread($fp, 8192);
fclose($fp);
$pkeyid = openssl_get_privatekey($priv_key);
if(!openssl_sign($to_sign,$signature,$pkeyid,'sha256')) {
$signature = 'sinfirma';
} else {
$signature = urlencode(base64_encode($signature));
}
return ('https://'.$bucket.'.storage.googleapis.com/'.$archivo.'?GoogleAccessId=XXXXXXX#developer.gserviceaccount.com&Expires='.$expires.'&Signature='.$signature);
}
I originally thought it was the url but this works as well.
"https://storage.googleapis.com/".$bucketName ."/

How to properly encrypt a JS generated RSA private key with a passphrase?

I have a php back-end that previously generated RSA private/public keypairs on its own, encrypting the private part with a given passphrase.
Now I'm using this library: http://travistidwell.com/jsencrypt/ to generate a keypair on client side. But I didn't find how to encrypt the private key with a passphrase using this library. So I tried using this: http://www.movable-type.co.uk/scripts/aes.html but it seems that a key I get doesn't work, I can't encrypt/decrypt using it on my php back-end and different keys management apps don't recognize the key.
What am I doing wrong and how to successfully encrypt the original JSEncrypt'ed private key properly with a passphrase?
This is how the keypair was generated on PHP:
$config = array(
"digest_alg" => "sha256",
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
"encrypt_key" => true
);
$keypair = openssl_pkey_new($config);
$pkey_pass = '123';
openssl_pkey_export($keypair, $privKey, $pkey_pass, $config);
$fp = fopen($keys_folder . '/private.pem', 'w');
fwrite($fp, $privKey);
fclose($fp);
$pubKey = openssl_pkey_get_details($keypair);
$fp = fopen($keys_folder . '/public.pem', 'w');
fwrite($fp, $pubKey);
fclose($fp);
Maybe you could adapt code from phpseclib. Quoting it:
if (!empty($this->password) || is_string($this->password)) {
$iv = Random::string(8);
$symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
$symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
$des = new TripleDES();
$des->setKey($symkey);
$des->setIV($iv);
$iv = strtoupper(bin2hex($iv));
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
"Proc-Type: 4,ENCRYPTED\r\n" .
"DEK-Info: DES-EDE3-CBC,$iv\r\n" .
"\r\n" .
chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) .
'-----END RSA PRIVATE KEY-----';
} else {
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
chunk_split(base64_encode($RSAPrivateKey), 64) .
'-----END RSA PRIVATE KEY-----';
}
src: https://raw.githubusercontent.com/phpseclib/phpseclib/master/phpseclib/Crypt/RSA.php
How to encrypt a JS generated RSA private key with a passphrase?
You have one of two choices. First, encrypt the entire key beofre it reaches disk. Then decrypt it before you use it. In this case, you treat the key like a file you want to encrypt.
Second, use PKCS #8, a.k.a. RFC 5208, Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification Version 1.2. In particular, see section 6 of RFC 5208, EncryptedPrivateKeyInfo.
You have a third option, but its not advised. The third option is to use an encrypted PEM encoding. Its not advisable because its been superseded by PKCS #8.
In the future, you will have a fourth option, and that is to use WebCrypto to store your key. In this case, you moved the problem of secure storage to the platform.
Unfortunately, I don't know about the library you are using, so I don't know what it may (or may not offer). But the answers above cover the OpenSSL bits of your question.

PHP OpenSSL Public Key Encryption With String Public Key

I have a public key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwKMDEDjbP5v/9kcvpQKf
IG3nU5Yid/tUNIeXBSDlxqhTEOKs8iQHXk0T17C4g7KHmrT2hxUomaAa2wwbfL+Z
4ppqvZZ4cu7CO6jaA0HyoBCU96siSuE0mPt8kU/PRA9+nAwu9lu9oYZUiVVJ3D4f
o2bc+jWWL4GGY+PdSlz81ZW5cW/LOmNs9D0jJIxbwNocHxGgJ+xTZ3JKp6AO4MvL
zXyipXu562N8wVc7UIgYYnvr63zFU8vzRL180X5x5MiJbjTYbfLH3z7qINPMZZLv
A5vzJ0HX3J8rG96tmFuUzopCnvf+WVLvaS2T5uMxieK9dfA32CFQp4i3cj39c2b7
NwIDAQAB
-----END PUBLIC KEY-----
stored as a base64 encoded string (in MySQL, set as $row['public_key'])
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF3S01ERURqYlA1di85a2N2cFFLZgpJRzNuVTVZaWQvdFVOSWVYQlNEbHhxaFRFT0tzOGlRSFhrMFQxN0M0ZzdLSG1yVDJoeFVvbWFBYTJ3d2JmTCtaCjRwcHF2Wlo0Y3U3Q082amFBMEh5b0JDVTk2c2lTdUUwbVB0OGtVL1BSQTkrbkF3dTlsdTlvWVpVaVZWSjNENGYKbzJiYytqV1dMNEdHWStQZFNsejgxWlc1Y1cvTE9tTnM5RDBqSkl4YndOb2NIeEdnSit4VFozSktwNkFPNE12TAp6WHlpcFh1NTYyTjh3VmM3VUlnWVludnI2M3pGVTh2elJMMTgwWDV4NU1pSmJqVFliZkxIM3o3cUlOUE1aWkx2CkE1dnpKMEhYM0o4ckc5NnRtRnVVem9wQ252ZitXVkx2YVMyVDV1TXhpZUs5ZGZBMzJDRlFwNGkzY2ozOWMyYjcKTndJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
in PHP. I'm trying to use this string to encrypt string data, but it just fails without telling me why when I use the following code:
$success = openssl_public_encrypt($data, $encrypted, base64_decode($row['public_key']));
When the above is run, $success is always false and $encrypted is blank. I've tried running the public key through openssl_pkey_get_public() and sending the resource to openssl_public_encrypt() with no luck either. Writing to a file is not an option, nor is storing the private key.
Does anyone know how to get this to work? (or does it work for everyone else and it's just a weird server issue?)
EDIT: Since there seems to be some confusion about my issue, here is the testing code I'm using and its output. (Note: I've removed the base64 encoding, just to see if that made any difference)
$pubkey = openssl_get_publickey($row['public_key']);
$publicKey = openssl_pkey_get_details($res);
$encrypted = null;
$success = openssl_public_encrypt($data, $encrypted, $pubkey);
print "\npubkey1 " . $row['public_key'];
print "\npubkey2 " . $pubkey;
print "\npubkey3 " . $publicKey;
print "\npubkey4 " . $publicKey["key"];
print "\nencryption " . ($success ? 'true' : 'false') . ' "' . $encrypted . '"';
$success = openssl_public_encrypt($data, $encrypted, $row['public_key']);
print "\nencryption2 " . ($success ? 'true' : 'false') . ' "' . $encrypted . '"';
Output:
pubkey1 -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA89FgfElm36q7iAf8frqa
o58naoROsAljaFbmztfnqlmzXfyijK5CNJFdkUCgsu2zGxN7UlGiBOassTd4ijWm
1rz6/ad9fGXplfMGxZxyPCz31VreSWXmTG/PeSIYs1Co+dibV3imYt5jTxfLs7BZ
WsT8nuLxGPw/o/gyKut0Ru+jXI2GgT4s3SylXinn/IbIA497SohqYA7/ViQnBwSL
ZKUysOx2QgBmc9m0viRqDSKNUtDw7+L7bjhlwgZUGr6fxfTuNj9PWo97aPSE74CD
owYYl2ToTboKSjZUszeNwQKpUnlHY/DBkwmYUJ7SAYDY70VNooadN5dZ4ehjdaka
6QIDAQAB
-----END PUBLIC KEY-----
pubkey2 Resource id #50
pubkey3
pubkey4
encryption false ""
encryption2 false ""
The key that you should pass to this function is a PHP resource object, and not the string representation of the key itself.
$pubkey = openssl_get_publickey(base64_decode($row['public_key']));
$success = openssl_public_encrypt($data, $encrypted, $pubkey);
So the issue actually relates to the data. PKI for php has a really small length restriction and can't be used to encrypt large amounts of data. Instead you're supposed to use PKI to encrypt a symmetric key which is then used to encrypt/decrypt data.
See more # How to encrypt long strings in PHP?

Categories