1

I want to encypt data to request api parameter. I converted my c# code to javascript but i got diff result:

C# code:

private byte[] GetPasswordInBytes(string password)
{
   SHA1Managed mSha1 = new SHA1Managed();
   var hashBytes = mSha1.ComputeHash(Encoding.UTF8.GetBytes(password));
   return hashByte;
}   

Javascipt Code:

getPasswordInBytes(password) {
  let bytes = CryptoJS.enc.Utf8.parse(password);
  let hashPass = CryptoJS.SHA1(bytes);
  return this.getBytes(hashPass);
}

getBytes(hash) {
  var byteArray = [];
  hash.words.forEach(function(i) {
    var k;
    for (var j = 3; j >= 0; j--) {
      k = (i >> (j * 8)) & 0xFF;
      k = k < 128 ? k : -(256 - k);
      byteArray.push(k);
    }
  });

  return byteArray;
}

input: password="123456"

output:

C#:

[124, 74, 141, 9, 202, 55, 98, 175, 97, 229, 149, 32, 148, 61, 194, 100, 148, 248, 148, 27]

Javascript:

[124, 74, -115, 9, -54, 55, 98, -81, 97, -27, -107, 32, -108, 61, -62, 100, -108, -8, -108, 27]

I just implemet new from above code:

C# code

  private byte[] GetPasswordInBytes(string password)
    {
      SHA1Managed mSha1 = new SHA1Managed();
      var hashBytes = mSha1.ComputeHash(Encoding.UTF8.GetBytes(password));           

      var keyBytes = new byte[16];
      Array.Copy(hashBytes, keyBytes, 16);//Copy first 128-bit.

      return keyBytes;
    }

    private string Encrypt(string plainText, string password)
    {
      byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
      byte[] keyBytes = GetPasswordInBytes(password);
      RijndaelManaged rijndaelManaged = new RijndaelManaged
      {
        Mode = CipherMode.CBC,
        Padding = PaddingMode.PKCS7,
        KeySize = 128,
        BlockSize = 128,
        Key = keyBytes,
        IV = keyBytes
      };

      byte[] cryptedBytes = rijndaelManaged.CreateEncryptor()
          .TransformFinalBlock(plainBytes, 0, plainBytes.Length);

      return Convert.ToBase64String(cryptedBytes);
    }

Javascript code

getPasswordInBytes(password) {
    let bytes = CryptoJS.enc.Utf8.parse(password);
    let hashPass =  CryptoJS.SHA1(bytes);    
    let byteArray = this.getBytes(hashPass);

    return byteArray.slice(0, 16);//Copy first 128-bit.
  } 



 getBytes(hash)
  {    
    var byteArray = [];
    hash.words.forEach(function (i) {
      var k;
      for (var j = 3; j >= 0; j--) {
        k = (i >> (j * 8)) & 0xFF;        
        byteArray.push(k);
      }
    });

    return byteArray;
  }    



  encrypt(clearText, password)
  {
    let key = this.getPasswordInBytes(password).toString();
    let iv = key;    
    let data = CryptoJS.enc.Latin1.parse(clearText);
    var encrypted = CryptoJS.AES.encrypt(
      data,
      key,
      { 
        keySize: 128,
        iv: iv,       
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      });     

    let result =  CryptoJS.enc.Base64.stringify( encrypted.ciphertext);   

    return result;
  }

call method: encrypt('cleart text','123456')

Out put:

C#: m8BOnfX+n9Fc90dZdV2vQQ==     
Javascript: 6qYSO7ZkTcesmZKvkFJz+g==  

In javascript the result was changed for each run

lV2NO3NpsERUQmXMOOzcvQ==    
H1Sla9/wrQXvKuTELPATDQ==    
WsMHHJLskuJxmEJe7PnAAg==  

UPDATE

 getPasswordInBytes(password) {
    let bytes = CryptoJS.enc.Utf8.parse(password);   
    let hashPass =  CryptoJS.SHA1(bytes);    
    let byteArray = this.getBytes(hashPass);
    return byteArray;
  }          

  encrypt(clearText, password)
  {
    let keyBytes = this.getPasswordInBytes(password);     
    let key = CryptoJS.lib.WordArray.create(keyBytes, 16);//128bit
    let iv = CryptoJS.lib.WordArray.create(keyBytes, 16);    
    let data = CryptoJS.enc.Utf8.parse(clearText);      
    var encrypted = CryptoJS.AES.encrypt(
      data,
      key,
      {        
        keySize:128,
        blockSize: 128,   
        iv: iv,        
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      });                    

    return encrypted.toString();            
  }

  getBytes(hash)
  {    
    var byteArray = [];
    hash.words.forEach(function (i) {
      var k;
      for (var j = 3; j >= 0; j--) {
        k = (i >> (j * 8)) & 0xFF;        
        byteArray.push(k);
      }
    });

    return byteArray;
  }

call method: encrypt('cleart text','123456')

Out put: still diffrence

C#: m8BOnfX+n9Fc90dZdV2vQQ==
Javascript: gVSE5CdyGxJJRbWaJiuyhg==
4
  • These are the same byte values actually, as far as i can tell. Either your Javascript code assumes signed byte value semantics, or JS itself interprets these byte values as Two's complement when outputting/displaying them (i don't know Javascript, and i haven't looked to closely at your JS code). For example, 141 decimal is in hexadecimal 0x8d. Interpreting this byte value as a signed byte value (using Twos complement), the byte value 0x8d represent the negative signed byte value -115. Another: the byte 229 decimal is hex 0xe5. The Two's complement of the signed byte -27 is also hex 0xe5 Commented Jun 21, 2019 at 15:15
  • @elgonzo thank for your explain Commented Jun 21, 2019 at 15:23
  • But, if you want to save the hassle of double parsing the result, and have the result look identical on both platforms, comment out this line: k = k < 128 ? k : -(256 - k); Commented Jun 21, 2019 at 15:27
  • results of javascript code is not same when it is each called Commented Jun 22, 2019 at 8:35

1 Answer 1

1

If you would remove the line k = k < 128 ? k : -(256 - k); from the code, the results would be the same.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.