<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 
 </head><body>
 
  <p>Hello,<br /></p>
  <p>This post relates to using openssl with an Entrust User Profile EPF file.<br /></p>
  <p>I had some success using openssl to extract certificates and keys from an EPF file.<br /></p>
  <p>This may be 18 to 21 years too late, but I successfully extracted the certificate and keys from the EPF file listed in the post:<br /></p>
  <p><a href="https://marc.info/?l=openssl-users&m=94888973208299&w=2">https://marc.info/?l=openssl-users&m=94888973208299&w=2</a>       <span style="color: rgb(0, 0, 0); font-size: 12pt;"><strong><span size="+1"><a style="color: rgb(0, 0, 0);" href="https://marc.info/?t=94888973700001&r=1&w=2">Entrust User Profile (again)</a></span></strong></span><br /></p>
  <p>and the info is likely useful for posts:<br /></p>
  <p><a href="https://marc.info/?l=openssl-users&m=101302596808738&w=2">https://marc.info/?l=openssl-users&m=101302596808738&w=2</a>       <span style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0); font-size: 12pt;"><strong><span size="+1"><a style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0);" href="https://marc.info/?t=101298904500002&r=1&w=2">RE: Entrust EPF File</a></span></strong></span><br /></p>
  <p><a href="https://marc.info/?l=openssl-users&m=92251200512812&w=2">https://marc.info/?l=openssl-users&m=92251200512812&w=2</a>       <span style="font-size: 12pt;"><strong><span size="+1">Entrust User Profile</span></strong></span></p>
  <p>I wrote a bash script to extract the Signing Certificate and Signing Key from the EPF file and the script includes the openssl commands which were used.<br /></p>
  <p>Included here are some sections of that script which I think might be useful for the old posts and the sections show the use of openssl.<br /></p>
  <p><br /></p>
  <p>...<br /></p>
  <p># Using the password and the salt, generate the encryption key and<br /># IV (initialization vector). Note that the salt is used in its<br /># base64 encoded form.<br /># The Password Based Encryption (PBE) Key Derivation Function (KDF)<br /># does not exactly match any option from RFC8018<br /># https://tools.ietf.org/html/rfc8018<br /># although there are similarities.<br /># Entrust uses SHA1 (and possibly MD5 in some versions) and an<br /># iteration count on the password and salt<br /># in order to generate the key and IV.<br /># Since SHA1 does not generate enough bytes for both the key and IV,<br /># (at least not for CAST5)<br /># the process is repeated, but this time the byte 0x01 is appended to<br /># the password and salt.<br /># The key and half of the IV come from the first pass. The rest of<br /># the IV comes from the second pass.<br /></p>
  <p>...<br /></p>
  <p># pass 1 to generate the key and part of the IV<br />echo "pass 1 to generate the key and part of the IV"<br />declare -i index<br />index=1<br />tmp_to_hash=$(echo -n "${epf_password}""${epf_salt}" | xxd -p -c 256)<br />while [ $index -lt $(($epf_hashcount + 1)) ]<br />do<br /> tmp_to_hash2="${tmp_to_hash}"<br /> tmp_to_hash=$(echo -n ${tmp_to_hash2} | xxd -p -r -c 256 | openssl dgst -sha1 -binary | xxd -p -c 256)<br /> ((index++))<br />done<br />pbe_partial=${tmp_to_hash}<br />echo "Treat the next line of output as a secret."<br />echo "pbe_partial = " ${pbe_partial}<br /></p>
  <p>...<br /></p>
  <p># At this stage we have the full Key and part of the IV.<br />encryption_key_in_hex=$(echo -n ${pbe_partial} | head --bytes=32)<br />encryption_iv_in_hex=$(echo -n ${pbe_partial} | tail --bytes=-8)<br /></p>
  <p>...<br /></p>
  <p># pass 2 to generate the rest of the IV<br />echo "pass 2 to generate the rest of the IV"<br />declare -i index<br />index=1<br />tmp_to_hash=$(echo -e -n "${epf_password}""${epf_salt}""\x01" | xxd -p -c 256)<br />while [ $index -lt $(($epf_hashcount + 1)) ]<br />do<br /> tmp_to_hash2="${tmp_to_hash}"<br /> tmp_to_hash=$(echo -n ${tmp_to_hash2} | xxd -p -r -c 256 | openssl dgst -sha1 -binary | xxd -p -c 256)<br /> ((index++))<br />done<br />pbe_partial=${tmp_to_hash}<br />echo "Treat the next line of output as a secret."<br />echo "pbe_partial = " ${pbe_partial}<br /></p>
  <p>...<br /></p>
  <p># Complete the IV.<br />encryption_iv_in_hex=$(echo -n ${encryption_iv_in_hex}; echo -n ${pbe_partial} | head --bytes=8)<br />echo "Treat the next line of output as a secret."<br />echo "encryption_key_in_hex = " ${encryption_key_in_hex}<br />echo "Treat the next line of output as a secret."<br />echo "encryption_iv_in_hex = " ${encryption_iv_in_hex}<br /></p>
  <p>...<br /></p>
  <p># Check if the generated key and IV are what we expect for this EPF file.<br /># Encrypting 8 bytes of all zeros should produce the Token found<br /># in the Password Token section in the EPF file.<br />test_token=$(echo -ne "\x00\x00\x00\x00\x00\x00\x00\x00" | openssl enc -cast5-cbc -nosalt -K ${encryption_key_in_hex} -iv ${encryption_iv_in_hex} | head --bytes=8 | od -A n -t x1 | tr -d '[:space:]')<br />echo "test_token = " ${test_token^^}<br />if [ ${epf_token} = ${test_token^^} ]<br />then<br /> echo "The tokens match. The supplied password is correct."<br />else<br /> echo "The tokens don't match. The supplied password is incorrect."<br /> echo "Exiting."<br /> exit 1<br />fi<br /></p>
  <p>...<br /></p>
  <p><br /></p>
  <p>With the key and IV you should be able to get your certificates, keys and other information from the EPF file (the full script in question does this for you for the Signing Cert and Key).  You'll want to use the decryption command (e.g. openssl enc -d -cast5-cbc -nosalt -K ${encryption_key_in_hex} -iv ${encryption_iv_in_hex}) again for the cert and the key, plus something like an "openssl x509 -inform DER" for the cert and an "openssl pkcs8 -topk8 -inform DER" for the key.  This combined with some non openssl commands such as base64, sed, head and tail (e.g. to remove some non standard headers and footers) and even a little python to verify the CRC.<br /></p>
  <p>I hope this helps someone out there although I realize the original posts are quite a while ago.<br /></p>
  <p><br /></p>
  <p><br /></p>
  <p>Thanks,<br /></p>
  <p>Deric<br /></p>
 
</body></html>