fpoirotte / tomcrypt
libtomcrypt 的 PHP 绑定
README
PHP 的 libtomcrypt 绑定。
为什么?
我编写这个扩展有两个原因
首先,我想学习如何编写 PHP 扩展。
PHP 7.0-7.1 中已经弃用了
mcrypt
扩展,而在 PHP 7.2 中已经完全移除了它。虽然我同意这个决定的理由(libmcrypt 自 2007 年以来就没有维护),但我还需要为我的某些项目寻找替代品。因此,我决定寻找一个具有以下特点的加密库
- 具有宽松的许可证(见下文)
- 简单的 API,以便我可以轻松编写对其的绑定(我不想学习 OpenSSL 的 API,例如)
- 相对较好的支持(例如,广泛打包、接收更新等)
安装
POSIX 系统(Linux 等)
您可以使用 pear
安装此扩展
wget https://github.com/fpoirotte/tomcrypt/archive/master.tar.gz tar zxvf master.tar.gz pear install tomcrypt-master/package.xml
它还将尝试自动将扩展添加到您的 php.ini
中。如果无法完成此操作,您可以手动通过将以下行添加到您的 php.ini
来启用扩展
extension=tomcrypt.so
Microsoft Windows
从 发布页面 下载预构建的 php_tomcrypt.dll
,或自己编译 DLL。
之后,只需将 DLL 放入您的 PHP 安装目录的 extension_dir
中,并将以下配置行添加到您的 php.ini
中
extension=php_tomcrypt.dll
用法
加密
使用如下代码加密一些明文数据
<?php $algo = TOMCRYPT_CIPHER_RIJNDAEL; $mode = TOMCRYPT_MODE_ECB; $plaintext = "Confidential msg"; $key = "some secret key!"; $ciphertext = tomcrypt_cipher_encrypt($algo, $key, $plaintext, $mode); ?>
您可以通过 tomcrypt_list_ciphers()
获取您的平台支持的加密算法列表。此扩展还提供了可以用于引用各种加密算法的常量
TOMCRYPT_CIPHER_3DES
TOMCRYPT_CIPHER_AES
TOMCRYPT_CIPHER_ANUBIS
TOMCRYPT_CIPHER_BLOWFISH
TOMCRYPT_CIPHER_CAMELLIA
TOMCRYPT_CIPHER_CAST5
TOMCRYPT_CIPHER_CHACHA
TOMCRYPT_CIPHER_DES
TOMCRYPT_CIPHER_KASUMI
TOMCRYPT_CIPHER_KHAZAD
TOMCRYPT_CIPHER_MULTI2
TOMCRYPT_CIPHER_NOEKEON
TOMCRYPT_CIPHER_RC2
TOMCRYPT_CIPHER_RC4
TOMCRYPT_CIPHER_RC5
TOMCRYPT_CIPHER_RC6
TOMCRYPT_CIPHER_RIJNDAEL
(TOMCRYPT_CIPHER_AES
的别名)TOMCRYPT_CIPHER_SAFER128
(TOMCRYPT_CIPHER_SAFERSK128
的别名)TOMCRYPT_CIPHER_SAFER64
(TOMCRYPT_CIPHER_SAFERSK64
的别名)TOMCRYPT_CIPHER_SAFERK128
TOMCRYPT_CIPHER_SAFERK64
TOMCRYPT_CIPHER_SAFERPLUS
TOMCRYPT_CIPHER_SAFERSK128
TOMCRYPT_CIPHER_SAFERSK64
TOMCRYPT_CIPHER_SOBER128
TOMCRYPT_CIPHER_SEED
TOMCRYPT_CIPHER_SKIPJACK
TOMCRYPT_CIPHER_TRIPLEDES
(TOMCRYPT_CIPHER_3DES
的别名)TOMCRYPT_CIPHER_TWOFISH
TOMCRYPT_CIPHER_XTEA
您可以通过 tomcrypt_list_modes()
获取支持的加密/解密模式列表。还提供了以下常量
TOMCRYPT_MODE_CBC
TOMCRYPT_MODE_CCM
TOMCRYPT_MODE_CFB
TOMCRYPT_MODE_CHACHA20POLY1305
TOMCRYPT_MODE_CTR
TOMCRYPT_MODE_EAX
TOMCRYPT_MODE_ECB
TOMCRYPT_MODE_F8
TOMCRYPT_MODE_GCM
TOMCRYPT_MODE_LRW
TOMCRYPT_MODE_OCB
TOMCRYPT_MODE_OCB3
TOMCRYPT_MODE_OFB
TOMCRYPT_MODE_STREAM
TOMCRYPT_MODE_XTS
备注
TOMCRYPT_MODE_STREAM
只适用于流密码(即 TOMCRYPT_CIPHER_RC4
、 TOMCRYPT_CIPHER_CHACHA
和 TOMCRYPT_CIPHER_SOBER128
)。同样,这些流密码也无法与其他模式一起使用。
解密
解密的工作方式与加密基本相同。
<?php $algo = TOMCRYPT_CIPHER_RIJNDAEL; $mode = TOMCRYPT_MODE_ECB; $key = "some secret key!"; $plaintext = tomcrypt_cipher_decrypt($algo, $key, $ciphertext, $mode); ?>
当然,为了使解密正常工作,加密和解密过程中应使用相同的算法(密码)、模式和密钥。
散列
可以使用以下代码轻松进行数据散列。
<?php $algo = TOMCRYPT_HASH_SHA256; // Returns the hash value for the given data in hexadecimal form $hash = tomcrypt_hash_string($algo, $data, false); // Returns the hash value for the given data in raw (binary) form $hash = tomcrypt_hash_string($algo, $data, true); // Returns the hash value for the given file in raw (binary) form $hash = tomcrypt_hash_file($algo, "/tmp/file", true); ?>
使用 tomcrypt_list_hashes()
获取支持的散列算法列表。与密码类似,还提供了一些常量来引用各种已知的散列算法。
TOMCRYPT_HASH_BLAKE2B_160
TOMCRYPT_HASH_BLAKE2B_256
TOMCRYPT_HASH_BLAKE2B_384
TOMCRYPT_HASH_BLAKE2B_512
TOMCRYPT_HASH_BLAKE2S_128
TOMCRYPT_HASH_BLAKE2S_160
TOMCRYPT_HASH_BLAKE2S_224
TOMCRYPT_HASH_BLAKE2S_256
TOMCRYPT_HASH_MD2
TOMCRYPT_HASH_MD4
TOMCRYPT_HASH_MD5
TOMCRYPT_HASH_RIPEMD128
TOMCRYPT_HASH_RIPEMD160
TOMCRYPT_HASH_RIPEMD256
TOMCRYPT_HASH_RIPEMD320
TOMCRYPT_HASH_SHA1
TOMCRYPT_HASH_SHA224
(TOMCRYPT_HASH_SHA2_224
的别名)TOMCRYPT_HASH_SHA256
(TOMCRYPT_HASH_SHA2_256
的别名)TOMCRYPT_HASH_SHA384
(TOMCRYPT_HASH_SHA2_384
的别名)TOMCRYPT_HASH_SHA512
(TOMCRYPT_HASH_SHA2_512
的别名)TOMCRYPT_HASH_SHA512_224
(TOMCRYPT_HASH_SHA2_512_224
的别名)TOMCRYPT_HASH_SHA512_256
(TOMCRYPT_HASH_SHA2_512_256
的别名)TOMCRYPT_HASH_SHA2_224
TOMCRYPT_HASH_SHA2_256
TOMCRYPT_HASH_SHA2_384
TOMCRYPT_HASH_SHA2_512
TOMCRYPT_HASH_SHA2_512_224
TOMCRYPT_HASH_SHA2_512_256
TOMCRYPT_HASH_SHA3_224
TOMCRYPT_HASH_SHA3_256
TOMCRYPT_HASH_SHA3_384
TOMCRYPT_HASH_SHA3_512
TOMCRYPT_HASH_TIGER
TOMCRYPT_HASH_WHIRLPOOL
消息认证码
可以使用以下代码生成消息认证码(MAC)。
<?php $algo1 = TOMCRYPT_MAC_HMAC; $hash = TOMCRYPT_HASH_SHA1; $key = "my secret key..."; $data = "some data here"; // Returns the HMAC for the given data in hexadecimal form, // using the SHA-1 hashing algorithm. $hmac = tomcrypt_mac_string($algo1, $hash, $key, $data, false); // Returns the PMAC for the given data in raw (binary) form, // using the Rijndael cipher algorithm. $algo2 = TOMCRYPT_MAC_PMAC; $cipher = TOMCRYPT_CIPHER_RIJNDAEL; $pmac = tomcrypt_mac_string($algo2, $cipher, $key, $data, true); // Returns the HMAC for the given file in raw (binary) form, // using the SHA-1 hashing algorithm. $hmac = tomcrypt_mac_file($algo1, $hash, $key, "/tmp/file", true); ?>
使用 tomcrypt_list_macs()
获取平台支持的 MAC 算法列表。以下常量也提供。
TOMCRYPT_MAC_BLAKE2B
TOMCRYPT_MAC_BLAKE2S
TOMCRYPT_MAC_CMAC
TOMCRYPT_MAC_F9
TOMCRYPT_MAC_HMAC
TOMCRYPT_MAC_PELICAN
TOMCRYPT_MAC_PMAC
TOMCRYPT_MAC_POLY1305
TOMCRYPT_MAC_XCBC
大多数这些 MAC 算法需要提供额外的算法。
TOMCRYPT_MAC_BLAKE2B
、TOMCRYPT_MAC_BLAKE2S
和TOMCRYPT_MAC_POLY1305
:不需要额外的算法(即您可以使用null
而不是算法)。TOMCRYPT_MAC_HMAC
:必须传递一些散列算法。- 其他 MAC 算法:必须传递一个密码。
请参阅关于 加密 和 散列 的文档,获取有关支持算法的更多信息。
(伪)随机数生成器
此扩展可以为用户提供随机生成数据,作为对 openssl_random_pseudo_bytes() 的替代。
可以使用以下代码生成(伪)随机数生成器。
<?php // Attempt to get 42 bytes of purely random data. // Returns FALSE if random data cannot be obtained in a secure way. $random = tomcrypt_rng_get_bytes(42, TOMCRYPT_RNG_SECURE); ?>
可用各种(伪)随机数生成器算法。
TOMCRYPT_RNG_CHACHA20
TOMCRYPT_RNG_FORTUNA
TOMCRYPT_RNG_RC4
TOMCRYPT_RNG_SECURE
TOMCRYPT_RNG_SOBER128
TOMCRYPT_RNG_YARROW
警告
除了 TOMCRYPT_RNG_SECURE
(这是 tomcrypt_rng_get_bytes()
使用的默认 RNG)之外,所有其他生成器都只是 PRNG,不应在需要真正随机数据时使用。
还可以将随机数生成器的状态导出/导入(例如,在 PHP 解释器重新启动之间重新播种 PRNG 或从 PRNG 获取可预测的输出)。
<?php $rand0 = tomcrypt_rng_get_bytes(8, TOMCRYPT_RNG_RC4); $state = tomcrypt_rng_export(TOMCRYPT_RNG_RC4); tomcrypt_rng_import(TOMCRYPT_RNG_RC4, $state); $rand1 = tomcrypt_rng_get_bytes(8, TOMCRYPT_RNG_RC4); tomcrypt_rng_import(TOMCRYPT_RNG_RC4, $state); $rand2 = tomcrypt_rng_get_bytes(8, TOMCRYPT_RNG_RC4); var_dump($rand0 == $rand1); // bool(false) var_dump($rand1 == $rand2); // bool(true) ?>
备注
由于 TOMCRYPT_RNG_SECURE
指的是系统的实际随机数生成器,因此无法导出/导入该生成器的状态。尝试这样做只会导致导出/导入一个空状态。
注意事项
以下是目前已知的问题列表
- 目前,使用
options
数组在解密过程中传递预期标签的认证加密(Authenticated Encryption)API 有点难以使用。 - 在流加密中使用加密/解密时的上下文会在每次操作之间重新初始化,因此无法在实际的流场景中使用。
许可证
libtomcrypt 在双重公共领域/WTFPL 许可证下发布。
php_tomcrypt 在 PHP 许可证的第 3.01 版本下发布。