2
16

Decode a signmii

Encoding a signmii consists in building a mark by concatenating a SHA1 in hexadecimal of 20 bytes, a GMT timestamp of 4 bytes and a serial number of 8 bytes, calculating the SHA1 of this mark in hexadecimal, concatenating this SHA1 with the mark, and cyphering the whole thing with the private part of an RSA key of 2048 bytes. The result is 256 bytes. To facilitate the display and the exchange of a signmii, the 256 bytes are encoded in BASE64 and filtered to replace the characters + (PLUS) and / (SLASH) of the BASE64 format by the characters - (DASH) and _ (UNDERSCORE) compatible with the format of a URL. A signmii is 342 bytes.

Download the certificate signmiikey.crt containing the public key which will allow you to decode a signmii.

The fingerprint of the certicate is:

13:B0:CD:83:00:EB:B8:4A:68:BB:C5:BE:31:84:82:8E:97:14:69:6E

You can control it with the openssl command:

$ openssl x509 -in signmiikey.crt -fingerprint -noout
SHA1 Fingerprint=13:B0:CD:83:00:EB:B8:4A:68:BB:C5:BE:31:84:82:8E:97:14:69:6E

Download the script checksignmii.php which contains the program in PHP which you will run to decode a signmii with the certificate signmiikey.crt.

The script checksignmii.php reads a file which contains a signmii, decodes it with the public key included in the file signmiikey.crt and displays the SHA1, the timestamp and the serial number encrypted in the signmii.

  1. define('USAGE', 'php -f %s signmiifile [certfile]');

The constant USAGE defines the proper usage of the command.

  1. $certfile='signmiikey.crt';

Initializes $certfile with the name of the file containing the certificate with the public key.

  1. function abort($msg, $code=1) {
  2.     echo $msg, PHP_EOL;
  3.     exit($code);
  4. }

The function abort displays $msg and quits the program returning the error code $code.

  1. function usage() {
  2.     global $argv;
  3.  
  4.     abort(sprintf(USAGE, basename($argv[0])), 1);
  5. }

The function usage quits the program displaying the usage of the command. The name of the program replaces the %s in the constant USAGE.

  1. function urldecodebase64($s) {
  2.     $s64 = str_replace(array('-', '_' ), array('+', '/'), $s);
  3.  
  4.     $mod4 = strlen($s64) % 4;
  5.     if ($mod4) {
  6.         $s64 .= substr('====', $mod4);
  7.     }
  8.  
  9.     return base64_decode($s64);
  10. }

The function urldecodebase64 reverses the encoding in BASE64 of a series of bytes where the characters + (PLUS) et / (SLASH) of BASE64 format have been replaced by the characters - (DASH) and _ (UNDERSCORE) compatible with the format of a URL.

  1. if (!($argc == 2 or $argc == 3)) {
  2.     usage();
  3. }
  4.  
  5. $infile=$argv[1];
  6.  
  7. if ($argc == 3) {
  8.     $certfile=$argv[2];
  9. }

Checks the number of arguments passed on the command-line. Extracts the name of file containing the signmii and the name of the file of the certificate with the public key if the command has 2 arguments.

  1. $lines=file($infile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
  2.  
  3. if (!$lines) {
  4.     abort('signmii?');
  5. }

Reads the file containing the sigmii. Quits the program if the file is empty.

  1. $s64='';
  2. foreach ($lines as $s) {
  3.     if ($s[0] != '#') {
  4.         $s64=$s;
  5.         break;
  6.     }
  7. }
  8.  
  9. if (strlen($s64) != 342) {
  10.     abort('signmii?');
  11. }

Skips the comment lines read in the file. Checks that the result is 342 characters.

  1. $crypto=urldecodebase64($s64);
  2.  
  3. if (strlen($crypto) != 256) {
  4.     abort('signmii?');
  5. }

Decodes the encoding in BASE64 with the function urldecodebase64. Checks that the result is 256 bytes.

  1. $pem=@file_get_contents($certfile);
  2. if (!$pem) {
  3.     abort('certfile' . '?');
  4. }
  5. $key=openssl_pkey_get_public($pem);
  6. if (!$key) {
  7.     abort('certfile' . '?');
  8. }
  9.  
  10. $r=openssl_public_decrypt($crypto, $sdata, $key);
  11. if (!$r) {
  12.     abort('signmii' . '?');
  13. }

Reads the certificate and extracts the public key from it. Decodes the signmii in binary form with the public key.

  1. $digest=substr($sdata, 0, 20);
  2.  
  3. $data=substr($sdata, 20, 32);
  4.  
  5. if ($digest != sha1($data, true)) {
  6.     abort('signmii' . '?');
  7. }

Checks the digest of the signmii.

  1. $sha1bin=substr($data, 0, 20);
  2. $r=unpack('H*', $sha1bin);
  3. $sha1=$r[1];
  4.  
  5. $gmtbin=substr($data, 20, 4);
  6. $r=unpack('N', $gmtbin);
  7. $gmt=gmdate('Y-m-d\TH:i:s\Z', $r[1]);
  8.  
  9. $serialbin=substr($data, 20+4, 8);
  10. $r=unpack('H*', $serialbin);
  11. $serial=$r[1];

Extracts the SHA1, the timestamp and the serial number contained in the decoded signmii.

  1. echo $sha1, ' ', $gmt, ' ', $serial, PHP_EOL;

Displays the SHA1, the timestamp and the serial number separated by a space.

EXAMPLE

# ed0847ae3231350b0153cd8b9c8f56b87ab37801 2014-05-19T21:36:11Z 0000000000000001

uIWPRlfPaB8VgkTHIg8IoTe72WtTLgL_vGoWjY8PfM9fFjwXb8LmvMsMGKVUUTvJOy-z536BC-GMCOaDDdHhcWqGEYyUlXULwwGBXQL7drGnnbTa0H4bCD1YME6H9q7xIdMqlD9pIS-CIAsAo1SYguOhHP9bBlZ_7vk91gmKmxJQi6ril_UlvUmvmjJbUSnoyvDBLPcOWTa0hPDiPKnLifaimHHzkKfLtD9Ck2DAam9G3q3ME0zayVOTTlFdyPsOwvM6SvOMqAi-iBV40Bg5Ky4wKJztDMiCCBCdx3k-jvMfVtZM61MoIDNaICeI59UYE-HL8cPX3CcRphXYdFmRHg

NOTE: The file can contain lines of comments starting with a # (HASHMARK) and empty lines.

Copy the 3 files signmiikey.crt, checksignmii.php and 1.signmii in the same folder. Run the script checksignmii.php with php passing the name of the file containing the signmii in argument:

$ php -f checksignmii.php 1.signmii
ed0847ae3231350b0153cd8b9c8f56b87ab37801 2014-05-19T21:36:11Z 0000000000000001

You can add the name of the file containing the certificate to the command-line:

$ php -f checksignmii.php 1.signmii signmiikey.crt
ed0847ae3231350b0153cd8b9c8f56b87ab37801 2014-05-19T21:36:11Z 0000000000000001

Comments

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]commande[/code], [code=langage]code source en c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].