Skip to content

Instantly share code, notes, and snippets.

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 diyism/4f4bf07c2cc814f3318f7e57d501ca5d to your computer and use it in GitHub Desktop.
Save diyism/4f4bf07c2cc814f3318f7e57d501ca5d to your computer and use it in GitHub Desktop.
aes-256-cbc / encrypt integer / shorten integer in php
<?php
$enc=encrypt_int(3524, 'aaaa1111bbbb3333cccc5555dddd7777');
echo $enc.'<hr>';
$int=decrypt_int($enc, 'aaaa1111bbbb3333cccc5555dddd7777');
echo $int.'<hr>';
//输出: 5e91d2b65b2a<hr>3524<hr>
//输出: a08f854f3ddf<hr>3524<hr>
//...
//实际的$iv_short.$ac_short, $crypt_text 分别是:
//5e91d2b6, 5b2a
//a08f854f, 3ddf
//...
//$key需要32个字符
function encrypt_int($int, $key)
{
$int=dechex($int);
$int=strlen($int)%2===0?hex2bin($int):hex2bin('0'.$int);
$hex=bin2hex(MoreUnsafeOpensslAES::encrypt($int, $key, 2, 3));
$rtn=base_convert($hex, 16, 36);
return $rtn;
}
function decrypt_int($enc, $key)
{
$hex=base_convert($enc, 36, 16);
$hex=strlen($hex)%2===0?hex2bin($hex):hex2bin('0'.$hex);
return hexdec(bin2hex(MoreUnsafeOpensslAES::decrypt($hex, $key, 2, 3)));
}
//参考http://www.coldxiangyu.com/2017/06/27/AES%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95/
//只有cfb, ofb才能保持内容长度不变, 所以把aes-256-cbc降级aes-256-cfb,
//但iv还是很长, 只能对iv动手脚(减少iv len并padding), 就变得more unsafe更不安全,
//要验证机制(Authentication Code)的话还要加ac len, 至少要占3位才防刷(1600万), 剩下的iv len至少2位才能对单个数据提供6万的变动空间
//用来加密很短的自增id之类还是可以凑合一用的
class MoreUnsafeOpensslAES
{
const METHOD = 'aes-256-cfb';
public static function encrypt($message, $key, $iv_len, $ac_len)
{
if (mb_strlen($key, '8bit') !== 32) {
throw new Exception("Needs a 256-bit key!");
}
$ivsize=openssl_cipher_iv_length(self::METHOD);
$iv=openssl_random_pseudo_bytes($ivsize);
$iv_short=substr($iv, 0, $iv_len);
$ac_short=substr(hash_hmac('md5', $message.$iv_short, $key, 1), 0, $ac_len);
$iv=str_pad($iv_short.$ac_short, $ivsize, "\0", STR_PAD_RIGHT);
$ciphertext = openssl_encrypt(
$message,
self::METHOD,
$key,
OPENSSL_RAW_DATA,
$iv
);
return $iv_short.$ac_short.$ciphertext;
}
public static function decrypt($message, $key, $iv_len, $ac_len)
{
if (mb_strlen($key, '8bit') !== 32) {
throw new Exception("Needs a 256-bit key!");
}
$ivsize = openssl_cipher_iv_length(self::METHOD);
$iv_short=mb_substr($message, 0, $iv_len, '8bit');
$ac_short=mb_substr($message, $iv_len, $ac_len, '8bit');
$iv=str_pad($iv_short.$ac_short, $ivsize, "\0", STR_PAD_RIGHT);
$ciphertext = mb_substr($message, $iv_len+$ac_len, null, '8bit');
$clear_text=openssl_decrypt(
$ciphertext,
self::METHOD,
$key,
OPENSSL_RAW_DATA,
$iv
);
$tmp=substr(hash_hmac('md5', $clear_text.$iv_short, $key, 1), 0, $ac_len);
if ($tmp!==$ac_short)
{
return '';
}
return $clear_text;
}
}
//因为mcrypt的名字MCRYPT_RIJNDAEL_128里128是key length 128而不是block size 256, 容易搞混淆,
//以及需要自己写PKCS7 Padding等问题, 因而php里aes-256-cbc推荐的实现是用openssl写:
//参考:https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong
class UnsafeOpensslAES
{
const METHOD = 'aes-256-cbc';
public static function encrypt($message, $key)
{
if (mb_strlen($key, '8bit') !== 32) {
throw new Exception("Needs a 256-bit key!");
}
$ivsize = openssl_cipher_iv_length(self::METHOD);
$iv = openssl_random_pseudo_bytes($ivsize);
$ciphertext = openssl_encrypt(
$message,
self::METHOD,
$key,
OPENSSL_RAW_DATA,
$iv
);
return $iv . $ciphertext;
}
public static function decrypt($message, $key)
{
if (mb_strlen($key, '8bit') !== 32) {
throw new Exception("Needs a 256-bit key!");
}
$ivsize = openssl_cipher_iv_length(self::METHOD);
$iv = mb_substr($message, 0, $ivsize, '8bit');
$ciphertext = mb_substr($message, $ivsize, null, '8bit');
return openssl_decrypt(
$ciphertext,
self::METHOD,
$key,
OPENSSL_RAW_DATA,
$iv
);
}
}
//整数的话用这两个函数更短小:
function shorten_int($id)
{
$id=dechex($id);
$id=strlen($id)%2===0?hex2bin($id):hex2bin('0'.$id);
$id=base64_encode($id);
$id=strtr($id, array('/'=>'_', '+'=>'-', '='=>''));
return $id;
}
function unshorten_int($id)
{
$id=strtr($id, array('-'=>'+', '_'=>'/'));
$id=base64_decode($id);
$id=bin2hex($id);
return base_convert($id, 16, 10);
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment