(Please note that the function I reference from the provided answer didn't work so I want to modify it to make it work or please provide a suitable solution to AES encryption in VueJS and decryption in PHP (or Laravel))
I have a password will be sent to Laravel API so I managed to encrypt and base64 it then send it to Laravel API. Here's the original encryption
And here's the encryption and encoding
var encryptedPassword = CryptoJS.AES.encrypt("123456", "Secret Passphrase");
const replacerFunc = () => {
const visited = new WeakSet();
return (key, value) => {
if (typeof value === "object" && value !== null) {
if (visited.has(value)) {
return;
}
visited.add(value);
}
return value;
};
};
let jsonString = JSON.stringify(encryptedPassword, replacerFunc());
let bs46encoded = btoa(unescape(encodeURIComponent(JSON.stringify(jsonString, replacerFunc()))))
I get this result
IntcIiRzdXBlclwiOntcIiRzdXBlclwiOnt9fSxcImNpcGhlcnRleHRcIjp7XCJ3b3Jkc1wiOlsxODQ4NTYxMTAzLDE1MjkyNDgyMTUsLTEwODg3MTk1MDEsLTEyNjAyOTYzNjJdLFwic2lnQnl0ZXNcIjoxNn0sXCJrZXlcIjp7XCIkc3VwZXJcIjp7fSxcIndvcmRzXCI6Wy0yODA5NjkxMjcsNzAzNjYxOTM0LDE1Mjg5OTYxNDEsLTEwOTU5OTQ2MDYsLTY4OTMyOTM1NiwtNDQ1MDc3MjE3LC0yMDM4MDY1MTUxLC0xNzI0MjIzMzE4LC0xNTk1Nzk5MDI5LDgxOTY1NjMwMSwtMTQzNTIxMDg2NCwxODkwMDcyNTc5XSxcInNpZ0J5dGVzXCI6MzJ9LFwiaXZcIjp7XCJ3b3Jkc1wiOlstMTU5NTc5OTAyOSw4MTk2NTYzMDEsLTE0MzUyMTA4NjQsMTg5MDA3MjU3OV0sXCJzaWdCeXRlc1wiOjE2fSxcImFsZ29yaXRobVwiOntcImtleVNpemVcIjo4LFwiJHN1cGVyXCI6e1wiY2ZnXCI6e1wibW9kZVwiOntcIiRzdXBlclwiOnt9LFwiRW5jcnlwdG9yXCI6e30sXCJEZWNyeXB0b3JcIjp7fX0sXCJwYWRkaW5nXCI6e30sXCIkc3VwZXJcIjp7fX0sXCJibG9ja1NpemVcIjo0LFwiJHN1cGVyXCI6e1wia2V5U2l6ZVwiOjQsXCJpdlNpemVcIjo0LFwiX0VOQ19YRk9STV9NT0RFXCI6MSxcIl9ERUNfWEZPUk1fTU9ERVwiOjIsXCIkc3VwZXJcIjp7XCJfbWluQnVmZmVyU2l6ZVwiOjB9fX19LFwiYmxvY2tTaXplXCI6NCxcImZvcm1hdHRlclwiOnt9LFwic2FsdFwiOntcIndvcmRzXCI6WzE5NDk1NjcxNjIsMjExODc0MjAyOF0sXCJzaWdCeXRlc1wiOjh9fSI=
In laravel
$objString = base64_decode($ecodedString);
And I get
"{\"$super\":{\"$super\":{}},\"ciphertext\":{\"words\":[-1208966431,415513002,-380428285,-1848403568],\"sigBytes\":16},\
"key\":{\"$super\":{},\"words\":[1997420112,-1528658502,-601329304,170123410,85401029,1271916135,-1899682466,856024313,-1926693888,505524620,1922976396,79922502],\"sigBytes\":32},
\"iv\":{\"words\":[-1926693888,505524620,1922976396,79922502],\"sigBytes\":16},\"algorithm\":{\"keySize\":8,\"$super\":{\"cfg\":{\"mode\":{\"$super\":{},\"Encryptor\":{},\"Decryptor\":{}},\"padding\":{},\"$super\":{}},\"blockSize\":4,\"$super\":{\"keySize\":4,\"ivSize\":4,\"_ENC_XFORM_MODE\":1,\"_DEC_XFORM_MODE\":2,\"$super\":{\"_minBufferSize\":0}}}},\"blockSize\":4,\"formatter\":{},
\"salt\":{\"words\":[3335652791,3193595722],\"sigBytes\":8}}"
Then
$this->cryptoJsAesDecrypt("Secret Passphrase", $objString);
public function cryptoJsAesDecrypt($passphrase, $jsonString){
$jsondata = json_decode($jsonString, true);
Log::alert("jsondata");
Log::alert($jsondata);
$salt = hex2bin($jsondata["salt"]);
$ct = base64_decode($jsondata["ct"]);
$iv = hex2bin($jsondata["iv"]);
$concatedPassphrase = $passphrase.$salt;
$md5 = array();
$md5[0] = md5($concatedPassphrase, true);
$result = $md5[0];
for ($i = 1; $i < 3; $i++) {
$md5[$i] = md5($md5[$i - 1].$concatedPassphrase, true);
$result .= $md5[$i];
}
$key = substr($result, 0, 32);
$data = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv);
Log::alert("data");
Log::alert($data);
return $data;
}
$jsondata returns
{"$super":{"$super":{}},"ciphertext":{"words":[-1208966431,415513002,-380428285,-1848403568],"sigBytes":16},
"key":{"$super":{},"words":[1997420112,-1528658502,-601329304,170123410,85401029,1271916135,-1899682466,856024313,-1926693888,505524620,1922976396,79922502],"sigBytes":32},
"iv":{"words":[-1926693888,505524620,1922976396,79922502],"sigBytes":16},"algorithm":{"keySize":8,"$super":{"cfg":{"mode":{"$super":{},"Encryptor":{},"Decryptor":{}},"padding":{},"$super":{}},"blockSize":4,"$super":{"keySize":4,"ivSize":4,"_ENC_XFORM_MODE":1,"_DEC_XFORM_MODE":2,"$super":{"_minBufferSize":0}}}},"blockSize":4,"formatter":{},
"salt":{"words":[3335652791,3193595722],"sigBytes":8}}
But can't get other variables correctly to decrypt this encryption and find the original plain text. How can I edit this function to make it work?
I try to clone this answer Encryption in JavaScript and decryption with PHP
I been working on this for days.
Our backend have a signature checking which is done using PHP:
private $HMAC_ALGO = 'md5';
public function decodeAndValidateMessage($data,$signature,$secretkey) {
if (!is_string($data)) {
throw new InvalidRequestException($data);
}
$decodedData = base64_decode($data);
// if not json returned the throw exception...
$jsonDecoded = json_decode($decodedData,true);
if (!$jsonDecoded) {
throw new InvalidRequestException($decodedData);
}
// validate
$signatureRef = base64_encode(hash_hmac($this->HMAC_ALGO,$decodedData,$secretkey,true));
if ($signature === $signatureRef) {
return $jsonDecoded;
} else {
throw new InvalidSignatureException();
}
}
I made it work on iOS:
func hmac(_ algorithm: HMACAlgorithm, key: String) -> String {
let cKey = key.cString(using: String.Encoding.utf8)
let cData = self.cString(using: String.Encoding.utf8)
var result = [CUnsignedChar](repeating: 0, count: Int(algorithm.digestLength()))
CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, Int(strlen(cKey!)), cData!, Int(strlen(cData!)), &result)
let hmacData:Data = Data(bytes: UnsafePointer<UInt8>(result), count: (Int(algorithm.digestLength())))
let hmacBase64 = hmacData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
print(String(hmacBase64))
return String(hmacBase64)
}
Any idea/help on doing this on Kotlin/Android? I'm being stuck on InvalidSignatureException error.
fun generateSignature(data : HashMap<String, Any>) : String {
val hmac = Mac.getInstance("HmacMD5")
hmac.init(SecretKeySpec(Constant.PRIVATEKEY.toByteArray(Charsets.UTF_8), hmac.algorithm))
return Base64.encodeToString(data.toString().toByteArray(),Base64.URL_SAFE + Base64.NO_PADDING + Base64.NO_CLOSE + Base64.NO_WRAP)
}
Thanks :D I really appreciate for any help :D
Update:
Just to make my question simpler?
Is it possible to make translate the iOS line of code to Kotlin?
enum HMACAlgorithm {
case md5, sha1, sha224, sha256, sha384, sha512
func toCCHmacAlgorithm() -> CCHmacAlgorithm {
var result: Int = 0
switch self {
case .md5:
result = kCCHmacAlgMD5
case .sha1:
result = kCCHmacAlgSHA1
case .sha224:
result = kCCHmacAlgSHA224
case .sha256:
result = kCCHmacAlgSHA256
case .sha384:
result = kCCHmacAlgSHA384
case .sha512:
result = kCCHmacAlgSHA512
}
return CCHmacAlgorithm(result)
}
func digestLength() -> Int {
var result: CInt = 0
switch self {
case .md5:
result = CC_MD5_DIGEST_LENGTH
case .sha1:
result = CC_SHA1_DIGEST_LENGTH
case .sha224:
result = CC_SHA224_DIGEST_LENGTH
case .sha256:
result = CC_SHA256_DIGEST_LENGTH
case .sha384:
result = CC_SHA384_DIGEST_LENGTH
case .sha512:
result = CC_SHA512_DIGEST_LENGTH
}
return Int(result)
}
}
this is how I call the function
var params : Dictionary
params.generateSignature()
fun generateSignature(data : HashMap) : String {
val hmac = Mac.getInstance("HmacMD5")
hmac.init(SecretKeySpec(Constant.PRIVATEKEY.toByteArray(Charsets.UTF_8), hmac.algorithm))
return Base64.encodeToString(data.toString().toByteArray(),Base64.URL_SAFE + Base64.NO_PADDING + Base64.NO_CLOSE + Base64.NO_WRAP)
}
Someone finally found out the answer.
My mistake is hashmap should be run under JSONObject
var obj = JsonObject(data)
and use obj.toString() :D
I want to translit xor crypting c++ to php. I use this function for crypting. I want decrypt this file with php.
wchar_t* encryptDecrypt(const wchar_t* toEncrypt, int length, wchar_t* EBKey) {
const wchar_t* key = EBKey;
wchar_t* output = new wchar_t[length];
for (int i = 0; i < length; i++) {
output[i] = toEncrypt[i] ^ key[i % wcslen(key)];
}
return output;
}
I read a xls file binary and crypt with encryptDecrypt
void encryptAndSave(char *src,AnsiString key) {
wchar_t *content;
wchar_t buffer[255];
wchar_t *result;
long size;
long fsize;
FILE *f=NULL;
f=fopen(src,"rb+");
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f,0, SEEK_SET);
content = (wchar_t *) malloc(size * sizeof (wchar_t));
fread(content, size, 1, f);
fclose(f);
content=encryptDecrypt(content,size,strToWchar_t(key));
f=fopen(src,"wb+");
fwrite(content, size, 1, f);
fclose(f);
}
I use this function to convertion key in to wchar_t
wchar_t* strToWchar_t(AnsiString value) {
int iSize = value.WideCharBufSize();
wchar_t *tmp = new wchar_t[iSize];
value.WideChar(tmp,iSize);
return tmp;
}
This code in php for decrypting
function encryptDecrypt($toEncrypt,$key) {
$output=array();
for ( $i = 0; $i < strlen($toEncrypt); $i++ ) {
$output[$i]= $toEncrypt[$i] ^ $key{$i % strlen($key)};
}
return $output;
}
But it is not rightly decrypting.When i crypt and decrypt with c++ this word, the result must be "qwerty" to "ﻎCDT#GH", but in php it does not work as c++. When i decrypt "ﻎCDT#GH" in php i get "яМp1v3e2s1u3y2", but i must get "qwerty". Please help to resolve this problem.
I am generating the SHA1 key in both PHP and Android to verify the file. But I am getting different keys for both PHP and Android.
Android :
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
byte[] buffer = new byte[65536];
InputStream fis = new FileInputStream(downloadFile.getPath());
int n = 0;
while (n != -1) {
n = fis.read(buffer);
if (n > 0) {
digest.update(buffer, 0, n);
}
}
fis.close();
byte[] digestResult = digest.digest();
log("CheckSum : " + byteArray2Hex(digestResult));
} catch (Exception e) {
log("Exception : " + e.getLocalizedMessage());
}
PHP:
echo ' \nSHA1 File hash of '. $filePath . ': ' . sha1_file($filePath);
Checksum Output:
PHP SHA1 CheckSum : e7a91cd4127149a230f3dcb5ae81605615d3e1be
Android SHA1 CheckSum : 19bcbd9d18a3880d2375bddb9181d75da3f32da0
Can anyone help how to handle this.
From this SO answer: https://stackoverflow.com/a/9855338/3393666 consider using this byteArray2Hex function:
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String byteArray2Hex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
I've tested it on java 1.7 vs PHP 7 and Android 5.0 compiled with SDK 23.
Hope this helps.
I need to convert this pice of PHP code to swift to create hashes, I am using a hash pattern in PHP to hash 2 strings with SHA256 and I would like to do this in swift, any ideas?
The SELF::SECRET is a secret key, and the SELF::HASH_PATTERN is my pattern and looks something like this: "00101010011100001010"
public function hash($first, $second) {
// Append the secret to the values.
$first = self::SECRET . $first;
$second = $second . self::SECRET;
// Hash the values.
$hash = hash_init('sha256');
hash_update($hash, $first);
$hash1 = hash_final($hash);
$hash = hash_init('sha256');
hash_update($hash, $second);
$hash2 = hash_final($hash);
// Create a new hash with pieces of the two we just made.
$result = '';
for ($i = 0; $i < strlen(self::HASH_PATTERN); $i++) {
$result .= substr(self::HASH_PATTERN, $i, 1) ? $hash2[$i] : $hash1[$i];
}
return $result;
}
Thanks!
UPDATE:
This is the part which I can't figure out:
$hash = hash_init('sha256');
hash_update($hash, $first);
$hash1 = hash_final($hash);
UPDATE:
After a few hours of doing research and coding I finally got it figured out.
This is the code that I wrote, maybe not the best, but it works :)
I used a small class from github for generating SHA256 strings in swift called NSHash
func create_token(first:String, second:String) -> String {
var newFirst = constants.secret + first as NSString
var newSecond = second + constants.secret as NSString
var hash1 = newFirst.SHA256()
var hash2 = newSecond.SHA256()
var result = ""
for var i = 0; i < countElements(constants.hash_pattern); i++ {
var character = "\(constants.hash_pattern[i])" as String
var number:Int = character.toInt()!
if number == 1 {
result = "\(result)\(hash2[i])"
}else {
result = "\(result)\(hash1[i])"
}
}
return result
}