encode by php and decode by js - php

because of gfw(great firewall) in our country , I have to encode content within http transfer (https is better , but its a second choice).
my way is use base64 encode by php and decode by js , then show in an iframe. but there's some problem in FF.
is there any better way to show base64 encoded string in browser , or another way to encode/decode ?

Try Something this:
function get_rnd_iv($iv_len)
{
$iv = '';
while ($iv_len-- > 0) {
$iv .= chr(mt_rand() & 0xff);
}
return $iv;
}
function md5_encrypt($string_value, $salt_key, $iv_len = 16)
{
$string_value .= "\x13";
$n = strlen($string_value);
if ($n % 16) $string_value .= str_repeat("\0", 16 - ($n % 16));
$i = 0;
$enc_text = get_rnd_iv($iv_len);
$iv = substr($salt_key ^ $enc_text, 0, 512);
while ($i < $n) {
$block = substr($string_value, $i, 8) ^ pack('H*', md5($iv));
$enc_text .= $block;
$iv = substr($block . $iv, 0, 512) ^ $salt_key;
$i += 16;
}
return urlencode(base64_encode($enc_text));
}
function md5_decrypt($enc_text, $salt_key, $iv_len = 16)
{
$enc_text = urldecode(base64_decode($enc_text));
$n = strlen($enc_text);
$i = $iv_len;
$string_value = '';
$iv = substr($salt_key ^ substr($enc_text, 0, $iv_len), 0, 512);
while ($i < $n) {
$block = substr($enc_text, $i, 8);
$string_value .= $block ^ pack('H*', md5($iv));
$iv = substr($block . $iv, 0, 512) ^ $salt_key;
$i += 16;
}
return preg_replace('/\\x13\\x00*$/', '', $string_value);
}

You could just set the innerHTML property of the body of the page...
As long as the encoded string that the JS is producing is valid HTML for the whole body, it should work fine, and then you don't have to do anything messy with iframes or whatever.

Related

convert mcrypt algorithm to openssl PHP (MCRYPT_TripleDES, MCRYPT_MODE_CBC)

I have got a decryption code that uses deprecated mcrypt, I need to convert this function to use openssl instead. There are many similar questions on Stackoverflow, but they did not help me.
here is the decryption function:
public function decrypt($str, $key){
//input
$str = '9ACF38C842B3522415364850EAD1909BD43FD590BE3CBD539AD5FF6C7465973ABD61E8371E03282605ED06C994DF394244B7E7DAD54A046510484FAA724330C4C95A527D7891151E7C195D4136CBD70A87D1BD1F75473CF6B45A3F2FA8231DD71FFB4150E0BF4B133ECAA5ACC82CFD74903E21BC6EECB4B33AF39B8AF0C183A64002CFC125A55685C69A13192F3A9A4FDAC860E90C3FB6D125285E9E687BEFBE05707E131FC7ABE25FE35AB114FAE8A247B8C0F3DBA8AA74396D10564B7A0617EED913ED';
$key = '10,10,10,10,10,10,10,10';
//expected output:
//'6706598320;67005551;100;00;YKB_TST_090519001330;0;0;https://setmpos.ykb.com/PosnetWebService/YKBTransactionService;posnettest.ykb.com;2225;N;0;Not authenticated;1557398383820;TL'
outputsrand((double) microtime() * 10000000);
$block = #mcrypt_get_block_size(MCRYPT_TripleDES, MCRYPT_MODE_CBC);
$td = #mcrypt_module_open(MCRYPT_TripleDES, '', MCRYPT_MODE_CBC, '');
$ks = #mcrypt_enc_get_key_size($td);
if (strlen($str) < 16 + 8) return false;
// Get IV
$iv = pack("H*", substr($str, 0, 16));
// Get Encrypted Data
$encrypted_data = pack("H*", substr($str, 16, strlen($str)-16-8));
// Get CRC
$crc = substr($str, -8);
// Check CRC
/*if (!$this->checkCrc(substr($str, 0, strlen($str)-8), $crc)) {
return "CRC is not valid! ($crc)";
}*/
// Initialize
#mcrypt_generic_init($td, substr(strtoupper(md5($key)), 0, $ks), $iv);
// Decrypt Data
$decrypted_data = #mdecrypt_generic($td, $encrypted_data);
$packing = ord($decrypted_data[strlen($decrypted_data) - 1]);
if ($packing and ($packing < $block)) {
for($P = strlen($decrypted_data) - 1; $P >= strlen($decrypted_data) - $packing; $P--) {
if (ord($decrypted_data[$P]) != $packing) {
$packing = 0;
}
}
}
return substr($decrypted_data, 0, strlen($decrypted_data) - $packing);
I tried:
$encrypted_data = pack("H*", substr($str, 16, strlen($str)-16-8));
$iv = pack("H*", substr($str, 0, 16));
/returns FALSE when sample input above given
$decrypted_data = openssl_decrypt($encrypted_data, 'des-ede3-cbc', $key, OPENSSL_RAW_DATA, $iv);
Can anybody help me please?
I missed key transformation step, doing this way worked:
$decrypted_data = openssl_decrypt($encrypted_data, 'des-ede3-cbc', substr(strtoupper(md5($key)), 0, 24), OPENSSL_RAW_DATA, $iv);

how is the encryption method using CryptoJS using the correct php function

I have javascript code for encryption like this :
var myPassword = '12345*abc';
var encrypted = CryptoJS.AES.encrypt(myString, myPassword);
document.getElementById("demo1").innerHTML = encrypted;
and I have a decryption function with php like this :
function decrypt($ciphertext, $key) {
$ciphertext = base64_decode($ciphertext);
if (substr($ciphertext, 0, 8) != "Salted__") {
return false;
}
$salt = substr($ciphertext, 8, 8);
$keyAndIV = evpKDF($key, $salt);
$decryptPassword = openssl_decrypt(
substr($ciphertext, 16),
"aes-256-cbc",
$keyAndIV["key"],
OPENSSL_RAW_DATA, // base64 was already decoded
$keyAndIV["iv"]);
return $decryptPassword;
}
function evpKDF($password, $salt, $keySize = 8, $ivSize = 4, $iterations = 1, $hashAlgorithm = "md5") {
$targetKeySize = $keySize + $ivSize;
$derivedBytes = "";
$numberOfDerivedWords = 0;
$block = NULL;
$hasher = hash_init($hashAlgorithm);
while ($numberOfDerivedWords < $targetKeySize) {
if ($block != NULL) {
hash_update($hasher, $block);
}
hash_update($hasher, $password);
hash_update($hasher, $salt);
$block = hash_final($hasher, TRUE);
$hasher = hash_init($hashAlgorithm);
// Iterations
for ($i = 1; $i < $iterations; $i++) {
hash_update($hasher, $block);
$block = hash_final($hasher, TRUE);
$hasher = hash_init($hashAlgorithm);
}
$derivedBytes .= substr($block, 0, min(strlen($block), ($targetKeySize - $numberOfDerivedWords) * 4));
$numberOfDerivedWords += strlen($block)/4;
}
return array(
"key" => substr($derivedBytes, 0, $keySize * 4),
"iv" => substr($derivedBytes, $keySize * 4, $ivSize * 4)
);
}
so far it works fine, and now I want to encrypt the string with the php function, I try to use a function like the code below, but it doesn't work,
function encrypt($string, $key) {
$salt = substr($string, 8, 8);
$keyAndIV = evpKDF($key, $string);
$encryptPassword = openssl_encrypt(
$string,
"aes-256-cbc",
$keyAndIV["key"],
OPENSSL_RAW_DATA,
$keyAndIV["iv"]);
return $encryptPassword;
}
can anyone help me please, how can I fix this issue, thanks.

Websocket - client doesn't receive data

I'm writing some app based on websockets (RFC 6455). Unfortunetly it looks like the client (testing on Chrome 18) doesn't receive data, but the server says it is sending...
Chrome doesn't say anything
Here are main server methods:
private function decode($payload) {
$length = ord($payload[1]) & 127;
if ($length == 126) {
$masks = substr($payload, 4, 4);
$data = substr($payload, 8);
} elseif ($length == 127) {
$masks = substr($payload, 10, 4);
$data = substr($payload, 14);
} else {
$masks = substr($payload, 2, 4);
$data = substr($payload, 6);
}
$text = '';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i % 4];
}
$text = base64_decode($text);
return $text;
}
private function encode($text) {
$text = base64_encode($text);
// 0x1 text frame (FIN + opcode)
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if ($length <= 125)
$header = pack('CC', $b1, $length);
elseif ($length > 125 && $length < 65536)
$header = pack('CCS', $b1, 126, $length);
else
$header = pack('CCN', $b1, 127, $length);
return $header . $text;
}
protected function process($user, $msg) {
echo '<< '.$msg.N;
if (empty($msg)) {
$this->send($user->socket, $msg);
return;
}
}
protected function send($client, $msg) {
$msg = $this->encode($msg);
echo '>> '.$msg.N;
socket_write($client, $msg, strlen($msg));
}
If you're sending a test message >125 bytes but <65536, your problem might be caused by a faulty format string to pack. I think this one should be 'CCn' (your current code writes the 2 bytes of the length in the wrong order).
If that doesn't help, you could try some client-side logging:
Does the onopen callback run to prove that the initial handshake completed successfully?
Do the onerror or onclose callbacks run, either after connection or after your server sends its message?

How can * be a safe hashed password?

phpass is a widely used hashing 'framework'. While evaluating phpass' HashPassword I came across this odd method fragment.
function HashPassword($password)
{
// <snip> trying to generate a hash…
# Returning '*' on error is safe here, but would _not_ be safe
# in a crypt(3)-like function used _both_ for generating new
# hashes and for validating passwords against existing hashes.
return '*';
}
Answer: we agree this class assumes that we test our hash for equality on * as a means of validating. This is why I will wrap this class, because it's interface is not great. I expect false in case of failure.
This is the complete phpsalt class:
# Portable PHP password hashing framework.
#
# Version 0.2 / genuine.
#
# Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
# the public domain.
#
#
#
class PasswordHash {
var $itoa64;
var $iteration_count_log2;
var $portable_hashes;
var $random_state;
function PasswordHash($iteration_count_log2, $portable_hashes)
{
$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
$iteration_count_log2 = 8;
$this->iteration_count_log2 = $iteration_count_log2;
$this->portable_hashes = $portable_hashes;
$this->random_state = microtime() . getmypid();
}
function get_random_bytes($count)
{
$output = '';
if (is_readable('/dev/urandom') &&
($fh = #fopen('/dev/urandom', 'rb'))) {
$output = fread($fh, $count);
fclose($fh);
}
if (strlen($output) < $count) {
$output = '';
for ($i = 0; $i < $count; $i += 16) {
$this->random_state =
md5(microtime() . $this->random_state);
$output .=
pack('H*', md5($this->random_state));
}
$output = substr($output, 0, $count);
}
return $output;
}
function encode64($input, $count)
{
$output = '';
$i = 0;
do {
$value = ord($input[$i++]);
$output .= $this->itoa64[$value & 0x3f];
if ($i < $count)
$value |= ord($input[$i]) << 8;
$output .= $this->itoa64[($value >> 6) & 0x3f];
if ($i++ >= $count)
break;
if ($i < $count)
$value |= ord($input[$i]) << 16;
$output .= $this->itoa64[($value >> 12) & 0x3f];
if ($i++ >= $count)
break;
$output .= $this->itoa64[($value >> 18) & 0x3f];
} while ($i < $count);
return $output;
}
function gensalt_private($input)
{
$output = '$P$';
$output .= $this->itoa64[min($this->iteration_count_log2 +
((PHP_VERSION >= '5') ? 5 : 3), 30)];
$output .= $this->encode64($input, 6);
return $output;
}
function crypt_private($password, $setting)
{
$output = '*0';
if (substr($setting, 0, 2) == $output)
$output = '*1';
if (substr($setting, 0, 3) != '$P$')
return $output;
$count_log2 = strpos($this->itoa64, $setting[3]);
if ($count_log2 < 7 || $count_log2 > 30)
return $output;
$count = 1 << $count_log2;
$salt = substr($setting, 4, 8);
if (strlen($salt) != 8)
return $output;
# We're kind of forced to use MD5 here since it's the only
# cryptographic primitive available in all versions of PHP
# currently in use. To implement our own low-level crypto
# in PHP would result in much worse performance and
# consequently in lower iteration counts and hashes that are
# quicker to crack (by non-PHP code).
if (PHP_VERSION >= '5') {
$hash = md5($salt . $password, TRUE);
do {
$hash = md5($hash . $password, TRUE);
} while (--$count);
} else {
$hash = pack('H*', md5($salt . $password));
do {
$hash = pack('H*', md5($hash . $password));
} while (--$count);
}
$output = substr($setting, 0, 12);
$output .= $this->encode64($hash, 16);
return $output;
}
function gensalt_extended($input)
{
$count_log2 = min($this->iteration_count_log2 + 8, 24);
# This should be odd to not reveal weak DES keys, and the
# maximum valid value is (2**24 - 1) which is odd anyway.
$count = (1 << $count_log2) - 1;
$output = '_';
$output .= $this->itoa64[$count & 0x3f];
$output .= $this->itoa64[($count >> 6) & 0x3f];
$output .= $this->itoa64[($count >> 12) & 0x3f];
$output .= $this->itoa64[($count >> 18) & 0x3f];
$output .= $this->encode64($input, 3);
return $output;
}
function gensalt_blowfish($input)
{
# This one needs to use a different order of characters and a
# different encoding scheme from the one in encode64() above.
# We care because the last character in our encoded string will
# only represent 2 bits. While two known implementations of
# bcrypt will happily accept and correct a salt string which
# has the 4 unused bits set to non-zero, we do not want to take
# chances and we also do not want to waste an additional byte
# of entropy.
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$output = '$2a$';
$output .= chr(ord('0') + $this->iteration_count_log2 / 10);
$output .= chr(ord('0') + $this->iteration_count_log2 % 10);
$output .= '$';
$i = 0;
do {
$c1 = ord($input[$i++]);
$output .= $itoa64[$c1 >> 2];
$c1 = ($c1 & 0x03) << 4;
if ($i >= 16) {
$output .= $itoa64[$c1];
break;
}
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 4;
$output .= $itoa64[$c1];
$c1 = ($c2 & 0x0f) << 2;
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 6;
$output .= $itoa64[$c1];
$output .= $itoa64[$c2 & 0x3f];
} while (1);
return $output;
}
function HashPassword($password)
{
$random = '';
if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
$random = $this->get_random_bytes(16);
$hash =
crypt($password, $this->gensalt_blowfish($random));
if (strlen($hash) == 60)
return $hash;
}
if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
if (strlen($random) < 3)
$random = $this->get_random_bytes(3);
$hash =
crypt($password, $this->gensalt_extended($random));
if (strlen($hash) == 20)
return $hash;
}
if (strlen($random) < 6)
$random = $this->get_random_bytes(6);
$hash =
$this->crypt_private($password,
$this->gensalt_private($random));
if (strlen($hash) == 34)
return $hash;
# Returning '*' on error is safe here, but would _not_ be safe
# in a crypt(3)-like function used _both_ for generating new
# hashes and for validating passwords against existing hashes.
return '*';
}
function CheckPassword($password, $stored_hash)
{
$hash = $this->crypt_private($password, $stored_hash);
if ($hash[0] == '*')
$hash = crypt($password, $stored_hash);
return $hash == $stored_hash;
}
}
I'm not sure exactly what you're asking. The comment directly says that it returns * on an error, so it's not "a safe hashed password", it indicates that an error occurred while trying to generate the hash. Strange choice for a return value, but it is what it is.
The reason that * can be returned on error is that * is not a possible hash value of any password. Therefore, returning that value will make a value that is obviously not a real hash value, and can't possibly match against another hash.

Is the salt contained in a phpass hash or do you need to salt its input?

phpass is a widely used hashing 'framework'.
Is it good practice to salt the plain password before giving it to PasswordHash (v0.2), like so?:
$dynamicSalt = $record['salt'];
$staticSalt = 'i5ininsfj5lt4hbfduk54fjbhoxc80sdf';
$plainPassword = $_POST['password'];
$password = $plainPassword . $dynamicSalt . $staticSalt;
$passwordHash = new PasswordHash(8, false);
$storedPassword = $passwordHash->HashPassword($password);
For reference the phpsalt class:
# Portable PHP password hashing framework.
#
# Version 0.2 / genuine.
#
# Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
# the public domain.
#
#
#
class PasswordHash {
var $itoa64;
var $iteration_count_log2;
var $portable_hashes;
var $random_state;
function PasswordHash($iteration_count_log2, $portable_hashes)
{
$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
$iteration_count_log2 = 8;
$this->iteration_count_log2 = $iteration_count_log2;
$this->portable_hashes = $portable_hashes;
$this->random_state = microtime() . getmypid();
}
function get_random_bytes($count)
{
$output = '';
if (is_readable('/dev/urandom') &&
($fh = #fopen('/dev/urandom', 'rb'))) {
$output = fread($fh, $count);
fclose($fh);
}
if (strlen($output) < $count) {
$output = '';
for ($i = 0; $i < $count; $i += 16) {
$this->random_state =
md5(microtime() . $this->random_state);
$output .=
pack('H*', md5($this->random_state));
}
$output = substr($output, 0, $count);
}
return $output;
}
function encode64($input, $count)
{
$output = '';
$i = 0;
do {
$value = ord($input[$i++]);
$output .= $this->itoa64[$value & 0x3f];
if ($i < $count)
$value |= ord($input[$i]) << 8;
$output .= $this->itoa64[($value >> 6) & 0x3f];
if ($i++ >= $count)
break;
if ($i < $count)
$value |= ord($input[$i]) << 16;
$output .= $this->itoa64[($value >> 12) & 0x3f];
if ($i++ >= $count)
break;
$output .= $this->itoa64[($value >> 18) & 0x3f];
} while ($i < $count);
return $output;
}
function gensalt_private($input)
{
$output = '$P$';
$output .= $this->itoa64[min($this->iteration_count_log2 +
((PHP_VERSION >= '5') ? 5 : 3), 30)];
$output .= $this->encode64($input, 6);
return $output;
}
function crypt_private($password, $setting)
{
$output = '*0';
if (substr($setting, 0, 2) == $output)
$output = '*1';
if (substr($setting, 0, 3) != '$P$')
return $output;
$count_log2 = strpos($this->itoa64, $setting[3]);
if ($count_log2 < 7 || $count_log2 > 30)
return $output;
$count = 1 << $count_log2;
$salt = substr($setting, 4, 8);
if (strlen($salt) != 8)
return $output;
# We're kind of forced to use MD5 here since it's the only
# cryptographic primitive available in all versions of PHP
# currently in use. To implement our own low-level crypto
# in PHP would result in much worse performance and
# consequently in lower iteration counts and hashes that are
# quicker to crack (by non-PHP code).
if (PHP_VERSION >= '5') {
$hash = md5($salt . $password, TRUE);
do {
$hash = md5($hash . $password, TRUE);
} while (--$count);
} else {
$hash = pack('H*', md5($salt . $password));
do {
$hash = pack('H*', md5($hash . $password));
} while (--$count);
}
$output = substr($setting, 0, 12);
$output .= $this->encode64($hash, 16);
return $output;
}
function gensalt_extended($input)
{
$count_log2 = min($this->iteration_count_log2 + 8, 24);
# This should be odd to not reveal weak DES keys, and the
# maximum valid value is (2**24 - 1) which is odd anyway.
$count = (1 << $count_log2) - 1;
$output = '_';
$output .= $this->itoa64[$count & 0x3f];
$output .= $this->itoa64[($count >> 6) & 0x3f];
$output .= $this->itoa64[($count >> 12) & 0x3f];
$output .= $this->itoa64[($count >> 18) & 0x3f];
$output .= $this->encode64($input, 3);
return $output;
}
function gensalt_blowfish($input)
{
# This one needs to use a different order of characters and a
# different encoding scheme from the one in encode64() above.
# We care because the last character in our encoded string will
# only represent 2 bits. While two known implementations of
# bcrypt will happily accept and correct a salt string which
# has the 4 unused bits set to non-zero, we do not want to take
# chances and we also do not want to waste an additional byte
# of entropy.
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$output = '$2a$';
$output .= chr(ord('0') + $this->iteration_count_log2 / 10);
$output .= chr(ord('0') + $this->iteration_count_log2 % 10);
$output .= '$';
$i = 0;
do {
$c1 = ord($input[$i++]);
$output .= $itoa64[$c1 >> 2];
$c1 = ($c1 & 0x03) << 4;
if ($i >= 16) {
$output .= $itoa64[$c1];
break;
}
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 4;
$output .= $itoa64[$c1];
$c1 = ($c2 & 0x0f) << 2;
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 6;
$output .= $itoa64[$c1];
$output .= $itoa64[$c2 & 0x3f];
} while (1);
return $output;
}
function HashPassword($password)
{
$random = '';
if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
$random = $this->get_random_bytes(16);
$hash =
crypt($password, $this->gensalt_blowfish($random));
if (strlen($hash) == 60)
return $hash;
}
if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
if (strlen($random) < 3)
$random = $this->get_random_bytes(3);
$hash =
crypt($password, $this->gensalt_extended($random));
if (strlen($hash) == 20)
return $hash;
}
if (strlen($random) < 6)
$random = $this->get_random_bytes(6);
$hash =
$this->crypt_private($password,
$this->gensalt_private($random));
if (strlen($hash) == 34)
return $hash;
# Returning '*' on error is safe here, but would _not_ be safe
# in a crypt(3)-like function used _both_ for generating new
# hashes and for validating passwords against existing hashes.
return '*';
}
function CheckPassword($password, $stored_hash)
{
$hash = $this->crypt_private($password, $stored_hash);
if ($hash[0] == '*')
$hash = crypt($password, $stored_hash);
return $hash == $stored_hash;
}
}
This is an answer from the original author himself:
Besides the actual hashing, phpass transparently generates random salts
when a new password or passphrase is hashed, and it encodes the hash
type, the salt, and the password stretching iteration count into the
"hash encoding string" that it returns. When phpass authenticates a
password or passphrase against a stored hash, it similarly transparently
extracts and uses the hash type identifier, the salt, and the iteration
count out of the "hash encoding string". Thus, you do not need to bother
with salting and stretching on your own - phpass takes care of these for
you.
Bottom line: it doesn't make sense to salt your password before "phpassing".
You don't really need two salts (i.e. the static salt is redundant; the dynamic salt is plenty) - the main purpose of a salt is to prevent rainbow-table attacks if the hashes are ever acquired by a malicious party, and the reason for dynamic salts is to further prevent special-case rainbow table generation from breaking all passwords simultaneously.
Aside from that though, it can't hurt to salt regardless of whether or not the library has salting built in (though unless you're passing it more info than just the item to be hashed, it doesn't really have anything to use as a dynamic salt, so chances are it doesn't salt for you if it's not already obvious that it does).

Categories