Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the tag from webcrypto AES-GCM encryption

I am trying to encrypt using webcrypto and decrypt using openssl in php. To decrypt in php i need an authentication tag. Is there a method to extract it from the ciphertext, or any other way i can get hold of it? The encryption in webcrypto is:

var stringToArrayBuffer=function(str){
  var bytes = new Uint8Array(str.length);
  for (var iii = 0; iii < str.length; iii++){
    bytes[iii] = str.charCodeAt(iii);
  }
  return bytes;
}
var arrayBufferToString=function(buffer){
  var str = "";
  for (var iii = 0; iii < buffer.byteLength; iii++){
    str += String.fromCharCode(buffer[iii]);
  }
  return str;
}
var vector=window.crypto.getRandomValues(new Uint8Array(12)),sendData={},key;
sendData.iv=btoa(arrayBufferToString(new Uint8Array(vector));

crypto.subtle.generateKey({name: "AES-GCM",length: 256,},false,["encrypt", "decrypt"]).then(function(oKey){
    console.log(oKey);
    key=oKey;
    sendData.key=btoa(arrayBufferToString(new Uint8Array(key));
}).catch(function(err){console.error("generateKey:",err);});

crypto.subtle.encrypt({name: "AES-GCM", iv: vector,tagLength: 128,},key,stringToArrayBuffer(input)).then(
  function(result){
    console.log('encrypted',new Uint8Array(result))
    encryptedDataString=arrayBufferToString(new Uint8Array(result));
    sendData.dataString=btoa(arrayBufferToString(new Uint8Array(result)));
  }
).catch(function(err){console.error("encryptData error:",err);});
like image 556
gerteb Avatar asked Sep 04 '25 04:09

gerteb


2 Answers

You need to slice tagLength bytes from the end of encrypted data

/**
 * Gets tag from encrypted data
 * 
 * @param {ArrayBuffer} encrypted Encrypted data
 * @param {number} tagLength Tag length in bits. Default 128 bits
 * @returns {ArrayBuffer}
 */
function GetTag(encrypted, tagLength) {
    if (tagLength === void 0) tagLength = 128;
    return encrypted.slice(encrypted.byteLength - ((tagLength + 7) >> 3))
}
like image 110
Microshine Avatar answered Sep 05 '25 17:09

Microshine


In php using openssl i wrote these two methods in my cryptographic class:

public function strToHex($string){
  $hex='';
  for ($i=0;$i<strlen($string);$i++){
    $ord=ord($string[$i]);
    $hexCode=dechex($ord);
    $hex.=substr('0'.$hexCode, -2);
  }
  return $hex;
}

public function symmetricDecrypt($key,$iv,$dataToDecrypt){
  $key=hex2bin($this->strToHex($key));
  $iv=hex2bin($this->strToHex($iv));
  $tag=substr($dataToDecrypt,-16);
  $dataToDecrypt=hex2bin($this->strToHex(substr($dataToDecrypt,0,-16)));
  $output = false;
  $output = openssl_decrypt($dataToDecrypt,'aes-256-gcm',$key,OPENSSL_RAW_DATA,$iv,$tag);
  try{if(!$output)throw new Exception("Cannot do symmetric decryption\n");}
  catch(Exception $e){
    $this->error.="Error occurred: ".$e->getMessage();
    while($e = openssl_error_string()){$this->error.=$e."\n";}
  }
  return $output;
}
like image 27
gerteb Avatar answered Sep 05 '25 16:09

gerteb