Skip to content

Instantly share code, notes, and snippets.

@WeaponMan
Last active May 29, 2016 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WeaponMan/73a8a99cc2b9ba7f69f515a258e04f84 to your computer and use it in GitHub Desktop.
Save WeaponMan/73a8a99cc2b9ba7f69f515a258e04f84 to your computer and use it in GitHub Desktop.
ISO9797 MAC algorithm 3
<?php
class ISO9797Algorithm3 {
const BLOCK_SIZE = 8;
const KEY_SIZE = 8;
public static function generate($input, $key) {
$inputChunked = str_split($input, self::BLOCK_SIZE);
$desKeys = self::splitKey($key);
$output = str_pad("", self::BLOCK_SIZE, "\0");
foreach ($inputChunked as $chunk) {
if (strlen($chunk) !== self::BLOCK_SIZE) {
$chunk = str_pad($chunk, self::BLOCK_SIZE, "\0");
}
$output = openssl_encrypt($chunk, "DES-CBC", $desKeys[0], OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $output);
}
$output = openssl_decrypt($output, "DES-ECB", $desKeys[1], OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
return openssl_encrypt($output, "DES-ECB", $desKeys[2], OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);
}
public static function generateKey() {
return self::key(self::KEY_SIZE * 2);
}
public static function generate3DesKey() {
return self::key(self::KEY_SIZE * 3);
}
private static function key($size) {
$key = str_pad("", $size, "\0");
for ($i = 0; $i < $size; $i++) {
$key[$i] = mt_rand() % 255;
}
return $key;
}
private static function splitKey($key) {
$keySize = strlen($key);
if (!in_array($keySize, [24, 16])) {
throw new InvalidArgumentException("Key must be size of 24 or 16 bytes");
}
$keys = str_split($key, self::BLOCK_SIZE);
if($keySize === 16){
$keys[] = $keys[0];
}
return $keys;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment