Login with digital certificate with PHP

Asked

Viewed 510 times

-2

Good afternoon guys, I’m trying to use the certsign login api https://www.certisign.com.br/produtos/desenvolvedores So far so good, I was able to send the request and get the return that is the token, but in the documentation it only give the option to decrypt the return with JAVA or . NET, I wonder if it is possible to do with PHP?

Token returned from certificate:

gYEzDDthl5m5Vl9ATMMqn76C4rLtaXhQL7Ns37CepNMvVDREK8v5QZ2dUGNvRmkRRMZvUDHQ9vtWtkWMX9uR2y9euFcyF38XYmI4pODbIOFWcertpluseZSgi6A0RigTxqLJcertplusqu7EM9uiY4zDSRo0th9ekdcertplus3p1NZXncertpluslPK70I3BefByG21certplus58mgtuFVwcSBR6JTHmIGcertplusn4qgAFoHJYHeuFfWzIv8sjHduIXIwrYG257i0oPZIb0D2/fmmthPvP3R9certplus8lw3RDlDz8/0uDPi39m5LJNFNuZ1certplusPh0mhPfdW/1Xepydu92yBwMsHJGZzOtwj6YVQZ8Jk/SAMWXZmmJbWTseQ7ggARrpZjUayc0VNeeTcertplusTuDyMl4sV8j7GmmC1RIkeklUAPWWwjauiOEOV9NdLLPUVVtfKzhuepwcertplusuhKV/hWGoxUYSRLttLzQWtd6khSp/q1YGeU1P5G1bbZyakvrReRcW09bpTJG6bcertplusPf/pv1TwEDFPcPWajVokxcertplusgXgyoGArcAewYBKIPeU/M2g7kQovAT1oGcertplusImL0ho/5RhtHvsQD2otwJpkeUt4awql4/wabgrsIVNKqV9certplusZpi0Kg2bv1EjliloVCKaOsoWdIioNNft73epHyGnR3PW5r9rK7Msy9ybmPk1OZKfcertpluscertplusfnbOE7CHjo/BGeDNUxY63AYh0o3af6RtUxUpOgYcertpluseccEnej12cw1P91gRmibSN/x6NLVIhVTzIKk3YNp7Rah4hYqcertplusTpDrKGdz26xpC5v4K8qdnc2GWLv58lDo0a9gffhctB40dPPzKrJM2DO7EjNFrO3Lu8BQWzi4Rp9iv/OJx/ZRtutDI3TVYl63GzcVAPUlTFXcertplus3B8U/Cp0dGv9Cm2Y5DANiusaKhVztYGBZx7EoLreRUe2Br//CKwrexzTlhoTXaET6iHTBuaXjK6j3tCDIYuecertplusuLpNWt5bGL65lCfwvqKcertplusM1eK2yExgk4kec7gUKp7tcertplusxxnRzEEtglOodAcertplusNIGrtmg6KDH98XSelVbT7IdRZSDWMB/aqFAVTlqQCcAqNfFealzcertplusRRccertplusvk0ZsMrQnLHtrr2T1horhoBItu4xJiTF0OUre0UMDpYQ6ToO6tBxM7sixuMW1iud8NMcertplusmbGJtEG1RFV0FIYpniCMzHZWE8qWcj9znaydqCsQKFlpEIwCFma8wzvw0XYDjw7gonEaVB06L3Fu8layg3crpdxw9wPerx/FACU6ZoJuINMjy12Ws5on6MCq6/0APTcOcertplusTaXhBFDA0xz2YFq/S6HFLIzUggWKjx0k6bc8dcertplusG0Ebw4M714eIAzzZhoIBcrwwivnoDVRIe67IHcqcertplus1k6t/YUBVVg8D/sdqDVcertplusRdZlvL2zbMPdcsI9UcGi/OKn3FrJByx1okafF/BbQRSPyeZZ4a2L8YHhrsV4ZFjqtl9JuablTe1DASZ6ExCJe9nwp0Br2/UfdU/GxYATzO7PFrfoohifn6WnHjp7rdcertplusWQdySlpJseCrScertplusukhdPKOM0cMsNLF/qGSwDq7SqkWkjMQyhRBpuFD4vNdcxFqtWjNb8Q7SZqICE84y3Gy5NnbUyLWAvBpA28VYW3lvpQqMA5ucertplusICbIM5ctvZvmOXWJ7oecNX/pW6AMdzAJiXfhMdFUyZZcertplusdhjnqU6SgvbF/ddVa5qSGPleFxgVYSa5WzsRuTWPXtCK6WscijFtRev0IGWqCP60UnZA0TrSTLMQeOC6It30v6eodtZHydikPP9vP4tKyFIk5UmuvvNNjm4mcertplusdkbnm3y3tInpcertplusX6322Uxf68C5dYn81yJcjnVXbkAKI/oYDEWvc55bE0M3RHDDoQ/LvjFxwN8B56XnoRodRRYWG2J79XWgziUz6P4Ha5pg7P7kKcertplusDNsgffFPk5oHqQiehQzyINCqFGU9tnRb99OtCXrQaq9kyPDsOE9LMOcertplusOwU6G54gib3TElhwSFrPNjNpfdcA8wjN4VumkethyWGyBcertplusCjznJACLTCySz9egmrmchuP9zDSUfXU/certplus657gPDUG6EPUeIzby0SPm95weoP5iZDvl2rjZRE0ny8SjP1UTd2Ud98tRuFMBVPjHTb89AH/1shaSSpeuXiwcertplusVff3fRy91ZTcertplusLbb5epYkGOpqHheUBGrGbXM59gF6SWTlobP3j7dOVVHgyQJ3xEBKn9aD6GZaa/AdI8wcBRCJxa4DYxSNWFMJUQpRyIvCl13P7SFrldmlzgH7uXrfrV8ehuaTdBMda/eSVgOqBs4Wmv6xoWBWn1Yg75XCnEUqWXK5QLc072yttr2OTqma5nxgsk2ppo3jJrfVZbyTkXF2ScFGhkwYXHjt0iM8iJso6xk/gNjiRkmRj9Jx0xcertpluskyNw6VlF8l1tmcertplusD1Gcj66rGs4QA21x/RsVQ94q9ZxohAB5Bndl113pLKLQKHcertplusOaFYvD2YYiq6nc7vI2nlUkee9dRXzrCcodUvNjvlx/Lrome5hnrNfQicertpluskayfCTaVRn83mPYsFZnCqsWbQEvsIQJTF6GvGWrybGO0pcKYp7kCuJcertpluslXU8D3UNExrSfs3certplusydpP3nT0ICaIrbXLB/X1JMxCIz5OtZChUEnJjONsh0I29UDttP5f6HT2GPxcUbA5M62eK3hEgu9wAxe883yj1ASdNf1CmqqqNenPa90j/2kGwStLd4ds/46tlj5nVOoy3rkNlD287tIcertplusHxV94APCq4Z0f3RfLC/AB6YVYbDcertpluscDcrPGrWm/XUsC1x7bSu5Ypfce7Ahw2af7lJgVEVWEajPWqfRNisn11u9XzzaykVBE7rGwmKHs13certplusyyOj/QnF5eiqOMsSNtCFFlLSk2XtEQiKuzXMTiyeRA1QNPbXLRpd7OjHj8uXPopUBTCtopWr2U1sadp67EFwcdDNTxCK51WrpwVUfNxfSQ9OwiPnO3EtOqlK8Be7HNafdzG2RnUiWHrDNXF5MT8TRzwJ5PVtzIciFojljKRLncGn8x7HIu1wcertplustCrNMpzQP/XX7aN92p4s7Eol3wXL7Pg2GMNslHnHwTPmG/5AWBH5EqBsnMYAl0SQ21O0EXboiMJ3eXAdBtJMPZPMtlqyjofBqBjnF4certplusi86kRuVlxXHgVbe1G/9WNnqjz6JsHNq8WmqQ7i71mC3K4ZD0lCUCur3bB8prpCypOAY5yWcN3qOdMfmDxXruauxh7HcertplusOMjvR6guvy0ftOUOiCcertplusEsVWQlmM7NXewRE1yY6aN1/KBpwDLDU6/dyN7zzTEPl1DfbuZHNaXkcertpluseIuuGykzgWvL5NwSVCHOtWvh54uJl1iOcertplusZjs2SN0rnWGxJAabEhdsukM5fBlydfrLhuM41HT2F7W17XNLGdGPUrQa2No2Y3NZZ2jqkeO/mkWlFSDW2Hac77JrvL7vVZ4Q9CJUg8certplusL08gVh1QLDjCI/xZ6DZlcCscertplusPhMIK6kpVxuo7cZqrCTAoPHgjtJJzcertplusPUCgo67c0lercFuzoCIoFCoDFRzdt2WYR42lYtGnWTkKIvdvGVFq/gK2RnmS2Ye/Kxo8o3XWrRYnLmDDcertplusGlIck0DwhmYtoE37nHNWGIcquGLLQahzKzLfhmdVmVPuQ9LO550E3xFQt40xcPklVX2wRVPlC4jcertplusroUqOFPN9VSkUXkINzcertplusfqgKZxCU6E6U9GSi0dlLYjjEjlcRsptBkBhKTDJVbFzlSxKV7certplusJ9TTLYYI5k/8/40FZZnWpYUI//we0OHn/V2KM89XPBDKahOLZtst/IAijbSyXqYNIQHwlMOtZ0/dUaVM0bccertplusT2dMyVL94C6xAXqI1ZlR26QFKilSQe0G7YsbmDNRJcuZcmAcertplusrDLb17Snk2DUVMYszjRDDQJLVq18ihPWYbBdvw5hxazc7O9gBg5WeNcertplus3Akp6Xkbrph9/SgA14VsFkQ9bIEDnG//Vo8W39joL5T9P8pzrqfW3UOSPqZcertplusaYx/r2UQwWPY9geHxwBR7z4kY6JRSShaPqMVZP5hUpLyQvIWMQ43tMwROkfuJANwssgJhqlw9R9jSgCcZMuJ5EUXLcEQenXy5hDAe01/JC5zkQ5oKubc54WUNduiLqYqvFYLpe3rCo0NcertplusXaHT4H2q1KFuZ3KQ12VGPPc3SCJ

Script to decrypt the return with JAVA:

// obter retorno encriptado da resposta
String ret = request.getParameter("cb");

// obter chave que foi feito o download
InputStream chave =
getServletContext().getResourceAsStream("/WEB-INF/keys/<sua_chave.pk>");

String schave = IOUtils.toString(chave, "UTF-8");

// usar client e chave para decriptar o retorno encriptado
String decriptado = CryptoLogin.decrypt(ret, schave);
</sua_chave.pk>

Script to decrypt return with . NET:

string retorno = Request["cb"];
string encryptionKey = "<conteúdo da chave criptográfica descarregada na etapa 2>";
retorno = CryptoLogin.Instance.DecryptText(retorno,encryptionKey);</conteúdo>
  • 1

    The problem is that the page does not specify the algorithms used and there is no place to know where "Cryptologin.", since it does not appear to be native. The "client download" is broken link.

  • as well with broken link?

  • When you click "Download the client here." and the "client" according to them is "This client refers to the cryptographic key manipulation component that will run on your application.". So this must be the code of CryptoLogin, being lucky. But, by clicking it does not allow me to download, so do not have to know what are the algorithms used. If you have the CertisignLoginClient-NET.zip attach here, so anyone can download and you can read the code yourself or tell whether or not it is the code referring to the CryptoLogin. Then, knowing the encryption algorithms used, you can replicate in PHP.

  • Follow the link to . net https://drive.google.com/file/d/14LZClYySfRomYmLYmtaGxmOeyLLsFQKT/view give me your contact here Whatsapp or Telegram.

  • I see now, it seems easy.

  • the application is . net or c#?

  • Did the answer work or not? If you found another solution you can enter and then mark it as the best answer too.

  • can help me ?

Show 4 more comments

1 answer

2

WARNING: I don’t have a Certisign record, I’ve never been a client of theirs and I don’t have any ties. In addition, this reply is only intended to be "compatible", using native PHP features, with the least amount of possible changes compared to the original, so you can compare and correct any errors.


Since I have no way to test it, and in order for you to analyze it for yourself, the code used in Decrypt(), in .NET is exactly:

   public string DecryptText(string encryptedString, string encryptionKey)
    {
      RijndaelManaged rijndaelManaged = new RijndaelManaged();
      rijndaelManaged.Mode = CipherMode.CBC;
      rijndaelManaged.Padding = PaddingMode.PKCS7;
      rijndaelManaged.KeySize = 128;
      rijndaelManaged.BlockSize = 128;
      byte[] inputBuffer = Convert.FromBase64String(encryptedString.Replace("certplus", "+"));
      byte[] bytes = Encoding.UTF8.GetBytes(encryptionKey);
      byte[] numArray = new byte[16];
      int length = bytes.Length;
      if (length > numArray.Length)
        length = numArray.Length;
      Array.Copy((Array) bytes, (Array) numArray, length);
      rijndaelManaged.Key = numArray;
      rijndaelManaged.IV = numArray;
      return Encoding.UTF8.GetString(rijndaelManaged.CreateDecryptor().TransformFinalBlock(inputBuffer, 0, inputBuffer.Length));
    }

    public string EncryptText(string textToEncrypt, string encryptionKey)
    {
      RijndaelManaged rijndaelManaged = new RijndaelManaged();
      rijndaelManaged.Mode = CipherMode.CBC;
      rijndaelManaged.Padding = PaddingMode.PKCS7;
      rijndaelManaged.KeySize = 128;
      rijndaelManaged.BlockSize = 128;
      byte[] bytes1 = Encoding.UTF8.GetBytes(encryptionKey);
      byte[] numArray = new byte[16];
      int length = bytes1.Length;
      if (length > numArray.Length)
        length = numArray.Length;
      Array.Copy((Array) bytes1, (Array) numArray, length);
      rijndaelManaged.Key = numArray;
      rijndaelManaged.IV = numArray;
      ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor();
      byte[] bytes2 = Encoding.UTF8.GetBytes(textToEncrypt);
      return Convert.ToBase64String(encryptor.TransformFinalBlock(bytes2, 0, bytes2.Length));
    }

The file has been obtained due to the comment.


Well, first they use RijndaelManaged, the AES uses the same algorithm. Luckily, they use the same pattern established by AES. That is, it has a 128 bit block size and has a 128 bit key. They use the mode CBC which is common, and does not change the size of the blocks, although they seem to use incorrectly. Already the padding seems to use the same PKCS7, unless specified by OPENSSL_ZERO_PADDING, then no padding is applied. Well, in bad we can use the obsolete mcrypt, but requires an older version of PHP and do not recommend using.

This is an attempt with the openssl, if nothing goes right try with the mcrypt:

function DecryptText(string $encryptedString, string $key) : string {

    // byte[] inputBuffer = Convert.FromBase64String(encryptedString.Replace("certplus", "+"));
    $inputBuffer = base64_decode(str_replace("certplus", "+", $encryptedString));

    // byte[] bytes = Encoding.UTF8.GetBytes(encryptionKey);
    $bytes = $key; // ?

    //byte[] numArray = new byte[16];
    $numArray = array_fill(0, 16, 0x00);

    //int length = bytes.Length;
    //if (length > numArray.Length)
    //   length = numArray.Length;
    $length = min(mb_strlen($bytes, '8bit'), 16);

    // Array.Copy((Array) bytes, (Array) numArray, length);
    for ($i = 0; $i < $length; $i ++) {
        $numArray[$i] = $bytes[$i];
    }

    // rijndaelManaged.Key = numArray;
    // rijndaelManaged.IV = numArray;
    $_Key = implode($numArray); // ?
    $_IV = implode($numArray); // ? Isso é um problema de segurança! Me parece incorreto, exceto se a chave for usada uma única vez!

    return openssl_decrypt($inputBuffer, AES-128-CBC, $_Key, 0, $_IV); // ? Talvez usar o OPENSSL_RAW_DATA e depois converter para UTF-8?
}

Already with mcrypt would be something like:

function DecryptText(string $encryptedString, string $key) : string {

    // byte[] inputBuffer = Convert.FromBase64String(encryptedString.Replace("certplus", "+"));
    $inputBuffer = base64_decode(str_replace("certplus", "+", $encryptedString));

    // byte[] bytes = Encoding.UTF8.GetBytes(encryptionKey);
    $bytes = $key; // ?

    //byte[] numArray = new byte[16];
    $numArray = array_fill(0, 16, 0x00);

    //int length = bytes.Length;
    //if (length > numArray.Length)
    //   length = numArray.Length;
    $length = min(mb_strlen($bytes, '8bit'), 16);

    // Array.Copy((Array) bytes, (Array) numArray, length);
    for ($i = 0; $i < $length; $i ++) {
        $numArray[$i] = $bytes[$i];
    }

    // rijndaelManaged.Key = numArray;
    // rijndaelManaged.IV = numArray;
    $_Key = implode($numArray); // ?
    $_IV = implode($numArray); // ?

    $_PaddingSize = ord($inputBuffer[mb_strlen($inputBuffer, '8bit') - 1]);  


    return mb_substr(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $_Key, $inputBuffer, MCRYPT_MODE_CBC, $_IV), 0, mb_strlen($inputBuffer, '8bit') - $_PaddingSize, '8bit'); // ? Talvez não precise remover o padding?!
}

Maybe you need to convert UTF-8 to Bytes, but PHP "has no bytes", explicitly, I don’t even remember what it was like, maybe we need the unpack and of pack.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.