0

JSEncrypt can sign and verify but PHP openssl_verify fails

Using JSEncrypt to sign/verify a message works fine. However when I send the data to a PHP server for verification using openssl_verify it returns:

error:0906D06C:PEM routines:PEM_read_bio:no start line

Any idea why?

//////////////browser side
var signatory = new JSEncrypt();
var privateKey = document.getElementById("privkey").value;
signatory.setPrivateKey(privateKey);
var message = document.getElementById("pseudo").value;
var rsa_sha256_signature = signatory.sign(message, CryptoJS.SHA256);
document.getElementById("email").value = rsa_sha256_signature;
console.log("signature: " + rsa_sha256_signature);

    /* verify */
    var verifier = new JSEncrypt();
    var publicKey = document.getElementById("pubkey").value;
    
    verifier.setPublicKey(publicKey);
    if (verifier.verify(message, rsa_sha256_signature, CryptoJS.SHA256)) {
     console.log("valid signature !");
    }else{
        console.log("invalid signature!")
    }  
    
/////////////data is sent to server:
req.open("POST", "sign.php", true); 
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 

var donnees = "message=" + document.getElementById('pseudo').value +
                        "&signature=" + document.getElementById('email').value +
                        "&key_pub=" + document.getElementById("pubkey").value;

req.send(donnees );     
    
/////////////server side        
$message = $_POST ['message'];

$entityBody = file_get_contents('php://input');
$detach = explode("&",$entityBody);

$cherche_signature = 'signature=';
$cherche_key_pub = 'key_pub=';


$foundEncryptedText="no";
foreach($detach as $value){
  if (strpos($value, $cherche_signature) !== false) {
      $found_signature = substr($value, strlen($cherche_signature));
  }
  if (strpos($value, $cherche_key_pub) !== false) {
      $foundkey_pub = substr($value, strlen($cherche_key_pub));
  }

}

$result = openssl_verify( $message , $found_signature , $foundkey_pub , OPENSSL_ALGO_SHA256 );
echo "valid= " . $result;
echo "erreur : <br>".openssl_error_string();
Joaquin
  • 79
  • 1
  • 4
  • Possibly a problem with the key / key format / key encoding, `$foundkey_pub`, maybe header and footer are missing. But this is rather a guess, because your post doesn't show how `$foundkey_pub` looks like. It's best to post concrete _test_ data, i.e. private and public key, data to be signed and signature. – Topaco Jul 01 '20 at 07:00
  • Thank you for your reply. Here are the keys I am using: – Joaquin Jul 01 '20 at 10:29
  • -----BEGIN PUBLIC KEY----- MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgGEgkNl9C7ec2G8McjsfzshoOEfr SNnN6AMYg5TpxWbtxHYcBAtuvJbnwUjmr16lFZVNJ4p2nQDICNvUvgHG7u58ekqy s5QNTrp+zxHraj/koRr5dSii5lEmAN5+v2dSZNrQ4BZVvrK5Tuk92jBr+NBvQ2Re 7XdJVsL231uKEirhAgMBAAE= -----END PUBLIC KEY----- – Joaquin Jul 01 '20 at 10:29
  • -----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgGEgkNl9C7ec2G8McjsfzshoOEfrSNnN6AMYg5TpxWbtxHYcBAtu vJbnwUjmr16lFZVNJ4p2nQDICNvUvgHG7u58ekqys5QNTrp+zxHraj/koRr5dSii 5lEmAN5+v2dSZNrQ4BZVvrK5Tuk92jBr+NBvQ2Re7XdJVsL231uKEirhAgMBAAEC gYAu54wsC7A55pu63RbZKJ4yt+neCWjwDfjqbc81fcNf1pkWtKbbYonekmMMMqMk ILMQm+bpfiiJ9RAaIV30+73sgrRHUiFy+eKjMoUiRyaiVbzBaHyj42JRLG/28FOF tfAdhRlu/3xcCQdwoMbdu77Fdr2t3+Hgu5zpmwxRQJBAIee .....I cannot paste the entire private key -----END RSA PRIVATE KEY----- – Joaquin Jul 01 '20 at 10:30
  • I actually meant _test_ data (especially _test_ keys) to reproduce the issue. In particular, don't post productive keys (i.e. delete the comments if these are productive keys). – Topaco Jul 01 '20 at 10:37
  • they are test keys ;-) – Joaquin Jul 01 '20 at 11:13
  • 1
    What is the value of `$result`? – Topaco Jul 01 '20 at 11:43
  • the value for $result =0 – Joaquin Jul 01 '20 at 11:58
  • Try the following in the JavaScript code: `var rsa_sha256_signature = signatory.sign(message, CryptoJS.SHA256, "sha256");`. Note the third parameter which places the digest ID before the hash. Otherwise, the signature does not comply with the specification for RSASSA-PKCS1-v1_5. – Topaco Jul 01 '20 at 12:29
  • already tried it and the error is: error:04091077:rsa routines:INT_RSA_VERIFY:wrong signature length. – Joaquin Jul 01 '20 at 12:41
  • var rsa_sha256_signature = signatory.sign(message, CryptoJS.SHA256, "sha256"); does not work. I tried php sign to https://8gwifi.org/rsasignverifyfunctions.jsp verify and it works. I also tried https://8gwifi.org/rsasignverifyfunctions.jsp sign and PHP verify and it works as well. The problem definitely comes from the client side :-( even though JSEncrypt sign and verify is successful – Joaquin Jul 01 '20 at 12:44
  • 1
    I can't reproduce that. In my tests JSEncrypt is only compatible with the website and OpenSSL if the third parameter is specified. So please _edit_ your question, post your _complete_ test keys there, as well as the data to be signed (`message`) and the signature (`rsa_sha256_signature`), so that I can try to reproduce the issue with your data. – Topaco Jul 01 '20 at 13:06
  • Sorry for all this mess. I found what my error is. I forgot to $sig64 = base64_decode($found_signature); followed by: $result = openssl_verify( $message , $sig64 , $foundkey_pub , OPENSSL_ALGO_SHA256 ); now it works. Thank you for your help. – Joaquin Jul 02 '20 at 03:55

0 Answers0