And*_*ang 46 php encryption cryptography aes encryption-symmetric
我在PHP中找到了en/decode字符串的示例.起初它看起来非常好,但它不会工作:-(
有谁知道问题是什么?
$Pass = "Passwort";
$Clear = "Klartext";
$crypted = fnEncrypt($Clear, $Pass);
echo "Encrypted: ".$crypted."</br>";
$newClear = fnDecrypt($crypted, $Pass);
echo "Decrypted: ".$newClear."</br>";
function fnEncrypt($sValue, $sSecretKey) {
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, $sDecrypted, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));
}
function fnDecrypt($sValue, $sSecretKey) {
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, base64_decode($sEncrypted), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)));
}
Run Code Online (Sandbox Code Playgroud)
结果是:
加密: boKRNTYYNp7AiOvY1CidqsAn9wX4ufz/D9XrpjAOPk8=
解密: —‚(ÑÁ ^ yË~F'¸®Ó–í œð2Á_B‰Â—
Sco*_*ski 78
除非您有破坏其他人的加密实现的经验,否则编写自己的加密通常是一个坏主意.
这里没有一个例子验证密文,这使得它们易受比特重写攻击.
<?php
// PECL libsodium 0.2.1 and newer
/**
* Encrypt a message
*
* @param string $message - message to encrypt
* @param string $key - encryption key
* @return string
*/
function safeEncrypt($message, $key)
{
$nonce = \Sodium\randombytes_buf(
\Sodium\CRYPTO_SECRETBOX_NONCEBYTES
);
return base64_encode(
$nonce.
\Sodium\crypto_secretbox(
$message,
$nonce,
$key
)
);
}
/**
* Decrypt a message
*
* @param string $encrypted - message encrypted with safeEncrypt()
* @param string $key - encryption key
* @return string
*/
function safeDecrypt($encrypted, $key)
{
$decoded = base64_decode($encrypted);
$nonce = mb_substr($decoded, 0, \Sodium\CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
$ciphertext = mb_substr($decoded, \Sodium\CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
return \Sodium\crypto_secretbox_open(
$ciphertext,
$nonce,
$key
);
}
Run Code Online (Sandbox Code Playgroud)
然后测试一下:
<?php
// This refers to the previous code block.
require "safeCrypto.php";
// Do this once then store it somehow:
$key = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_KEYBYTES);
$message = 'We are all living in a yellow submarine';
$ciphertext = safeEncrypt($message, $key);
$plaintext = safeDecrypt($ciphertext, $key);
var_dump($ciphertext);
var_dump($plaintext);
Run Code Online (Sandbox Code Playgroud)
这可以在您将数据传递到客户端的任何情况下使用(例如,没有服务器端存储的会话的加密cookie,加密的URL参数等),并且具有相当高的确定性,即最终用户无法破译或可靠地篡改用它.
由于libsodium是跨平台的,因此也可以更轻松地与PHP通信,例如Java applet或本机移动应用程序.
注意:如果您特别需要将libsodium提供的加密cookie添加到您的应用程序,我的雇主Paragon Initiative Enterprises正在开发一个名为Halite的库,它可以为您完成所有这些工作.
zz1*_*433 53
$sDecrypted并且$sEncrypted 在您的代码中未定义.查看有效的解决方案(但不安全!):
这个例子不安全!不要用它!
$Pass = "Passwort";
$Clear = "Klartext";
$crypted = fnEncrypt($Clear, $Pass);
echo "Encrypred: ".$crypted."</br>";
$newClear = fnDecrypt($crypted, $Pass);
echo "Decrypred: ".$newClear."</br>";
function fnEncrypt($sValue, $sSecretKey)
{
return rtrim(
base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256,
$sSecretKey, $sValue,
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB
),
MCRYPT_RAND)
)
), "\0"
);
}
function fnDecrypt($sValue, $sSecretKey)
{
return rtrim(
mcrypt_decrypt(
MCRYPT_RIJNDAEL_256,
$sSecretKey,
base64_decode($sValue),
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB
),
MCRYPT_RAND
)
), "\0"
);
}
Run Code Online (Sandbox Code Playgroud)
但是这个代码中存在其他问题使得它不安全,特别是使用ECB(不是加密模式,只能在其上定义加密模式的构建块).请参阅Fab Sa的答案,快速解决最严重的问题,以及Scott如何做到这一点的答案.
bla*_*ade 39
如果您不想对 15行代码中可解决的内容使用重依赖,请使用内置的OpenSSL函数.大多数PHP安装都附带OpenSSL,它在PHP中提供快速,兼容和安全的AES加密.嗯,只要您遵循最佳实践,它就是安全的.
以下代码:
IV是一个公共信息,每个消息都需要随机.哈希确保数据未被篡改.
function encrypt($plaintext, $password) {
$method = "AES-256-CBC";
$key = hash('sha256', $password, true);
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv);
$hash = hash_hmac('sha256', $ciphertext . $iv, $key, true);
return $iv . $hash . $ciphertext;
}
function decrypt($ivHashCiphertext, $password) {
$method = "AES-256-CBC";
$iv = substr($ivHashCiphertext, 0, 16);
$hash = substr($ivHashCiphertext, 16, 32);
$ciphertext = substr($ivHashCiphertext, 48);
$key = hash('sha256', $password, true);
if (!hash_equals(hash_hmac('sha256', $ciphertext . $iv, $key, true), $hash)) return null;
return openssl_decrypt($ciphertext, $method, $key, OPENSSL_RAW_DATA, $iv);
}
Run Code Online (Sandbox Code Playgroud)
用法:
$encrypted = encrypt('Plaintext string.', 'password'); // this yields a binary string
echo decrypt($encrypted, 'password');
// decrypt($encrypted, 'wrong password') === null
Run Code Online (Sandbox Code Playgroud)
Fab*_* Sa 26
有关信息MCRYPT_MODE_ECB不使用IV(初始化向量).ECB模式将您的消息划分为块,每个块都单独加密.我真的不推荐它.
CBC模式使用IV使每条消息都是唯一的.建议使用CBC,而不是使用ECB.
示例:
<?php
$password = "myPassword_!";
$messageClear = "Secret message";
// 32 byte binary blob
$aes256Key = hash("SHA256", $password, true);
// for good entropy (for MCRYPT_RAND)
srand((double) microtime() * 1000000);
// generate random iv
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);
$crypted = fnEncrypt($messageClear, $aes256Key);
$newClear = fnDecrypt($crypted, $aes256Key);
echo
"IV: <code>".$iv."</code><br/>".
"Encrypred: <code>".$crypted."</code><br/>".
"Decrypred: <code>".$newClear."</code><br/>";
function fnEncrypt($sValue, $sSecretKey) {
global $iv;
return rtrim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, $sValue, MCRYPT_MODE_CBC, $iv)), "\0\3");
}
function fnDecrypt($sValue, $sSecretKey) {
global $iv;
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, base64_decode($sValue), MCRYPT_MODE_CBC, $iv), "\0\3");
}
Run Code Online (Sandbox Code Playgroud)
您必须存储IV以解码每条消息(IV 不是秘密的).每条消息都是唯一的,因为每条消息都有唯一的IV.
这是一个AES encryption使用 实现的可行解决方案openssl。它使用密码块链接模式(CBC 模式)。因此,除了 dataand 之外key,您还可以指定ivandblock size
<?php
class AESEncryption {
protected $key;
protected $data;
protected $method;
protected $iv;
/**
* Available OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING
*
* @var type $options
*/
protected $options = 0;
/**
*
* @param type $data
* @param type $key
* @param type $iv
* @param type $blockSize
* @param type $mode
*/
public function __construct($data = null, $key = null, $iv = null, $blockSize = null, $mode = 'CBC') {
$this->setData($data);
$this->setKey($key);
$this->setInitializationVector($iv);
$this->setMethod($blockSize, $mode);
}
/**
*
* @param type $data
*/
public function setData($data) {
$this->data = $data;
}
/**
*
* @param type $key
*/
public function setKey($key) {
$this->key = $key;
}
/**
* CBC 128 192 256
CBC-HMAC-SHA1 128 256
CBC-HMAC-SHA256 128 256
CFB 128 192 256
CFB1 128 192 256
CFB8 128 192 256
CTR 128 192 256
ECB 128 192 256
OFB 128 192 256
XTS 128 256
* @param type $blockSize
* @param type $mode
*/
public function setMethod($blockSize, $mode = 'CBC') {
if($blockSize==192 && in_array('', array('CBC-HMAC-SHA1','CBC-HMAC-SHA256','XTS'))){
$this->method=null;
throw new Exception('Invalid block size and mode combination!');
}
$this->method = 'AES-' . $blockSize . '-' . $mode;
}
/**
*
* @param type $data
*/
public function setInitializationVector($iv) {
$this->iv = $iv;
}
/**
*
* @return boolean
*/
public function validateParams() {
if ($this->data != null &&
$this->method != null ) {
return true;
} else {
return FALSE;
}
}
//it must be the same when you encrypt and decrypt
protected function getIV() {
return $this->iv;
}
/**
* @return type
* @throws Exception
*/
public function encrypt() {
if ($this->validateParams()) {
return trim(openssl_encrypt($this->data, $this->method, $this->key, $this->options,$this->getIV()));
} else {
throw new Exception('Invalid params!');
}
}
/**
*
* @return type
* @throws Exception
*/
public function decrypt() {
if ($this->validateParams()) {
$ret=openssl_decrypt($this->data, $this->method, $this->key, $this->options,$this->getIV());
return trim($ret);
} else {
throw new Exception('Invalid params!');
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用示例:
<?php
$data = json_encode(['first_name'=>'Dunsin','last_name'=>'Olubobokun','country'=>'Nigeria']);
$inputKey = "W92ZB837943A711B98D35E799DFE3Z18";
$iv = "tuqZQhKP48e8Piuc";
$blockSize = 256;
$aes = new AESEncryption($data, $inputKey, $iv, $blockSize);
$enc = $aes->encrypt();
$aes->setData($enc);
$dec=$aes->decrypt();
echo "After encryption: ".$enc."<br/>";
echo "After decryption: ".$dec."<br/>";
Run Code Online (Sandbox Code Playgroud)
这些是使用AES256 CBC通过 PHP 加密/解密字符串的紧凑方法:
function encryptString($plaintext, $password, $encoding = null) {
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($plaintext, "AES-256-CBC", hash('sha256', $password, true), OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext.$iv, hash('sha256', $password, true), true);
return $encoding == "hex" ? bin2hex($iv.$hmac.$ciphertext) : ($encoding == "base64" ? base64_encode($iv.$hmac.$ciphertext) : $iv.$hmac.$ciphertext);
}
function decryptString($ciphertext, $password, $encoding = null) {
$ciphertext = $encoding == "hex" ? hex2bin($ciphertext) : ($encoding == "base64" ? base64_decode($ciphertext) : $ciphertext);
if (!hash_equals(hash_hmac('sha256', substr($ciphertext, 48).substr($ciphertext, 0, 16), hash('sha256', $password, true), true), substr($ciphertext, 16, 32))) return null;
return openssl_decrypt(substr($ciphertext, 48), "AES-256-CBC", hash('sha256', $password, true), OPENSSL_RAW_DATA, substr($ciphertext, 0, 16));
}
Run Code Online (Sandbox Code Playgroud)
用法:
$enc = encryptString("mysecretText", "myPassword");
$dec = decryptString($enc, "myPassword");
Run Code Online (Sandbox Code Playgroud)
编辑:这是新版本的函数,使用AES256 GCM和PBKDF2作为密钥派生,更安全。
function str_encryptaesgcm($plaintext, $password, $encoding = null) {
if ($plaintext != null && $password != null) {
$keysalt = openssl_random_pseudo_bytes(16);
$key = hash_pbkdf2("sha512", $password, $keysalt, 20000, 32, true);
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("aes-256-gcm"));
$tag = "";
$encryptedstring = openssl_encrypt($plaintext, "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag, "", 16);
return $encoding == "hex" ? bin2hex($keysalt.$iv.$encryptedstring.$tag) : ($encoding == "base64" ? base64_encode($keysalt.$iv.$encryptedstring.$tag) : $keysalt.$iv.$encryptedstring.$tag);
}
}
function str_decryptaesgcm($encryptedstring, $password, $encoding = null) {
if ($encryptedstring != null && $password != null) {
$encryptedstring = $encoding == "hex" ? hex2bin($encryptedstring) : ($encoding == "base64" ? base64_decode($encryptedstring) : $encryptedstring);
$keysalt = substr($encryptedstring, 0, 16);
$key = hash_pbkdf2("sha512", $password, $keysalt, 20000, 32, true);
$ivlength = openssl_cipher_iv_length("aes-256-gcm");
$iv = substr($encryptedstring, 16, $ivlength);
$tag = substr($encryptedstring, -16);
return openssl_decrypt(substr($encryptedstring, 16 + $ivlength, -16), "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
$enc = str_encryptaesgcm("mysecretText", "myPassword", "base64"); // return a base64 encrypted string, you can also choose hex or null as encoding.
$dec = str_decryptaesgcm($enc, "myPassword", "base64");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
201869 次 |
| 最近记录: |