1

我正在尝试做:

  1. 使用 web.crypto 加密文本,
  2. 使用 AesCryptoServiceProvider 解密文本我的代码中没有任何异常,但解密与我加密的纯文本不匹配

解密后的明文字节相同,但字符串编码不起作用

我正在使用随机 iv,密钥和明文是恒定的。

function cryptoSys(plaintext,KeyString){
        var iVec=window.crypto.getRandomValues(new Uint8Array(16));                        
        var encryptSuccessFunc=(encrypt)=> { AfterEncrypt(BytearrayToString(iVec),arraybufferTostring(encrypt));}
        var ImportKeySuccessFunc= (keyObj)=>{                  
                                  window.crypto.subtle.encrypt(                
                                   {name:"AES-CBC", iv:iVec},
                                   keyObj,
                                  StringToByteArray(plaintext)
                                   ).then(encryptSuccessFunc);           

         window.crypto.subtle.importKey(
            "raw", 
            StringToByteArray(KeyString),
            {name:"AES-CBC", length:128},
            true,
            ["encrypt","decrypt"]
            ).then(ImportKeySuccessFunc);
}

之后,我使用 json 发送 iVec,密文

 function AfterEncrypt(iVec,ciphertext)
    {            
        var plaintext="String to Encrypt";
        if(iVec==null)
            return;
        var send2server= {"ciphertext":ciphertext,
            "iVec":iVec,
            "plaintext":plaintext};            
        var objectDataString = JSON.stringify(send2server);            
        sendJSONtoserver(objectDataString,"getDelayedBid");                  
    }

我正在使用以下实用程序功能:

    function StringToByteArray(strString) {            

        var byteArray = new Uint8Array(strString.length);
        for (var i=0; i<strString.length; i++) {
            byteArray[i] = strString.charCodeAt(i);
        }
        return byteArray;
    }
    function BytearrayToString(arrayBuffer) {            
        var strString = "";                        
        for (var i=0; i<arrayBuffer.byteLength; i++) {                
            strString += String.fromCharCode(arrayBuffer[i]);
        }
        return strString;
    }
     function arraybufferTostring(buf) {
        return String.fromCharCode.apply(null, new Uint8Array(buf));
    }

服务器端接受密钥,并假设解密:

public string DecryptCipher(Encoding u16, string cipherText, string key,string iVec)
    {
        byte[] ciphertextBytes = clearZeros(u16.GetBytes(cipherText)); 
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 128; //minimun key length
        aes.Key = clearZeros(u16.GetBytes(key)); 
        aes.IV = clearZeros(u16.GetBytes(iVec));
        aes.Padding = PaddingMode.PKCS7;
        aes.Mode = CipherMode.CBC;
        ICryptoTransform cryptoTrans = aes.CreateDecryptor(aes.Key, aes.IV);
        byte[] plaintextBytes = cryptoTrans.TransformFinalBlock(ciphertextBytes, 0, ciphertextBytes.Length);
        cryptoTrans.Dispose();
        return Convert.ToBase64String(plaintextBytes);
    }

我也有这个实用功能:

private byte [] clearZeros(byte [] bytearray)
    {
        byte[] ans = new byte[bytearray.Length / 2];
        for (int i = 0; i < bytearray.Length / 2; i++)
            ans[i] = bytearray[2 * i];
        return ans;
    }

我从 anthor 函数中获取参数:

public ActionResult getDelayedBid([FromBody] DelayedSubmission delaySub)
    {
        if (delaySub.ciphertext == null)
            return Json("Failure", JsonRequestBehavior.AllowGet);
        Encoding u16LE = Encoding.Unicode;        
        String decrypetedMessageLE = new Encryption().DecryptCipher(u16LE, delaySub.ciphertext,  getKeyFromDB(), delaySub.iVec);                
        if (decrypetedMessageLE.Equals(delaySub.plaintext) )
            {
                return Json("Success", JsonRequestBehavior.AllowGet);
            }
        return Json("Failure", JsonRequestBehavior.AllowGet);
}
4

1 回答 1

1

我使用了错误的编码,例如

Convert.ToBase64String(plaintextBytes);

我应该用

Encoding.ASCII.GetString(plaintextBytes);

于 2017-05-07T15:50:09.250 回答