【问题标题】:How to get the tag from webcrypto AES-GCM encryption如何从 webcrypto AES-GCM 加密中获取标签
【发布时间】:2017-10-06 09:24:24
【问题描述】:

我正在尝试使用 webcrypto 加密并使用 php 中的 openssl 解密。要在 php 中解密,我需要一个身份验证标签。有没有一种方法可以从密文中提取它,或者我可以通过其他任何方式来获取它? webcrypto中的加密方式是:

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);});

【问题讨论】:

  • 从最后切掉?
  • 我如何从 var "result" 中分割它?
  • 在 php 中,标签是一个长度为 16 的 utf-8 字符串。如果我在 javascript 中加密一个长度为 10 的字符串,我得到一个长度为 26 的加密 utf-8 字符串。我只是将最后 16 个字符并将它们用作 php 中的标记?
  • 刚刚尝试从加密字符串中切出最后 16 个字符。不好。
  • 您的解决方案是什么?谢谢。

标签: javascript php encryption


【解决方案1】:

您需要从加密数据的末尾分割tagLength 字节

/**
 * 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))
}

【讨论】:

    【解决方案2】:

    在使用 openssl 的 php 中,我在我的密码学类中编写了这两个方法:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 2021-11-07
      • 2019-01-01
      • 2021-11-07
      • 2021-04-14
      • 1970-01-01
      • 2021-09-24
      相关资源
      最近更新 更多