简体   繁体   English

在 Angular 加密,在 C# 解密

[英]Encrypting in Angular and Decrypt on C#

I am having the code to encrypt data on Angular, But I don't know how to decrypt on server side我有加密 Angular 数据的代码,但我不知道如何在服务器端解密

  var panno = CryptoJS.AES.encrypt("FEAPS8905Q", "myPassword").toString();

Encrypted as U2FsdGVkX19mi5mXlJ14Lj0XcJBbqMPDzi/UeNXK4Cw= in angular, after sending the encrypted using Http.post method, I am not getting the exact data, instead, getting楀뢖᷈鍩ԏ건뫨샞일䜍钚䁞在 angular 中加密为U2FsdGVkX19mi5mXlJ14Lj0XcJBbqMPDzi/UeNXK4Cw= ,在使用 Http.post 方法发送加密后,我没有得到确切的数据,而是得到楀뢖᷈鍩ԏ건뫨샞일䜍钚䁞

I used this reference also Decrypting on C# , but I am getting some data like壓섢⻫捼笺ﵑ戛ꔉ됒퍿誁累♟꘶콒ꚦ我也在C# 上使用了这个参考解密,但我得到了一些数据,如壓섢⻫捼笺ﵑ戛ꔉ됒퍿誁累♟꘶콒ꚦ

public string Decrypt(string cipherText)
    {
        string EncryptionKey = "myPassword";
        cipherText = cipherText.Replace(" ", "+");
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] {  
            0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76  });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.Padding = PaddingMode.None;
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(cipherBytes, 0, cipherBytes.Length);
                    cs.Close();
                }
                cipherText = Encoding.Unicode.GetString(ms.ToArray());
            }
        }
        return cipherText;
    }

CryptoJS.AES.encrypt(text, password) implicitly derives encryption key and iv from your password using derivation algorithm which is kind of not-native for C#. CryptoJS.AES.encrypt(text, password)使用派生算法从你的密码中隐式派生出加密密钥和 iv,这种算法不是 C# 原生的。 Instead of relying on that implicit derivation - it's better to explicitly do that yourself, using well known algorithm such as PBKDF2.与其依赖于隐式推导,不如自己使用众所周知的算法(如 PBKDF2)显式地执行此操作。

Key derivation is needed because your password can have arbitrary size, but given algorithm (AES) needs key of specific size, for example 256 bits.需要密钥派生,因为您的密码可以具有任意大小,但给定算法 (AES) 需要特定大小的密钥,例如 256 位。 So we need to go from arbitrary length password to fixed size key (in irreversible way).所以我们需要从任意长度的密码到固定大小的密钥(以不可逆的方式)。

Sample javascript code:示例 JavaScript 代码:

function encrypt (msg, pass) {
  // random salt for derivation
  var keySize = 256;
  var salt = CryptoJS.lib.WordArray.random(16);
  // well known algorithm to generate key
  var key = CryptoJS.PBKDF2(pass, salt, {
      keySize: keySize/32,
      iterations: 100
    });
  // random IV
  var iv = CryptoJS.lib.WordArray.random(128/8);      
  // specify everything explicitly
  var encrypted = CryptoJS.AES.encrypt(msg, key, { 
    iv: iv, 
    padding: CryptoJS.pad.Pkcs7,
    mode: CryptoJS.mode.CBC        
  });
  // combine everything together in base64 string
  var result = CryptoJS.enc.Base64.stringify(salt.concat(iv).concat(encrypted.ciphertext));
  return result;
}

Decrypting that in C# is now easy:在 C# 中解密它现在很容易:

public static string Decrypt(string cipherText, string password) {
    byte[] cipherBytes = Convert.FromBase64String(cipherText);
    using (Aes encryptor = Aes.Create()) {
        // extract salt (first 16 bytes)
        var salt = cipherBytes.Take(16).ToArray();
        // extract iv (next 16 bytes)
        var iv = cipherBytes.Skip(16).Take(16).ToArray();
        // the rest is encrypted data
        var encrypted = cipherBytes.Skip(32).ToArray();
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, salt, 100);
        encryptor.Key = pdb.GetBytes(32);
        encryptor.Padding = PaddingMode.PKCS7;
        encryptor.Mode = CipherMode.CBC;
        encryptor.IV = iv;
        // you need to decrypt this way, not the way in your question
        using (MemoryStream ms = new MemoryStream(encrypted)) {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Read)) {
                using (var reader = new StreamReader(cs, Encoding.UTF8)) {
                    return reader.ReadToEnd();
                }
            }
        }
    }
}    

If you understand the consequences, you can use fixed salt (or for example fixed salt per user in your application), and reduce number of iterations in PBKDF2.如果您了解后果,您可以使用固定盐(或例如在您的应用程序中为每个用户使用固定盐),并减少 PB​​KDF2 中的迭代次数。 Don't use fixed IV though, and don't use part of key as IV either.不要使用固定的 IV,也不要使用部分密钥作为 IV。

Encrypt in node.js:在 node.js 中加密:

    var crypto = require('crypto');
var key = '00000000000000000000000000000000'; //replace with your key
var iv = '0000000000000000'; //replace with your IV
var cipher = crypto.createCipheriv('aes256', key, iv)
var crypted = cipher.update(authorizationKey, 'utf8', 'base64')
crypted += cipher.final('base64');
console.log(crypted);

decrypt c#解密c#

    string keyString = "00000000000000000000000000000000"; //replace with your key
string ivString = "0000000000000000"; //replace with your iv

byte[] key = Encoding.ASCII.GetBytes(keyString);
byte[] iv = Encoding.ASCII.GetBytes(ivString);

using (var rijndaelManaged =
        new RijndaelManaged { Key = key, IV = iv, Mode = CipherMode.CBC })
        {
            rijndaelManaged.BlockSize = 128;
            rijndaelManaged.KeySize = 256;
            using (var memoryStream =
                   new MemoryStream(Convert.FromBase64String(AuthorizationCode)))
            using (var cryptoStream =
                   new CryptoStream(memoryStream,
                       rijndaelManaged.CreateDecryptor(key, iv),
                       CryptoStreamMode.Read))
            {
                return new StreamReader(cryptoStream).ReadToEnd();
            }
        }

source: https://gsferreira.com/archive/2015/02/how-to-encrypt-in-nodejs-and-decrypt-in-c-sharp/来源: https : //gsferreira.com/archive/2015/02/how-to-encrypt-in-nodejs-and-decrypt-in-c-sharp/

work for me !为我工作!

Found matching algorithms for both Angular and C# to encrypt & Decrypt text cipherPhrase text contain both key and IV separated by a demiliter pipe找到 Angular 和 C# 的匹配算法来加密和解密文本 cipherPhrase 文本包含密钥和 IV,由分号管道分隔

Angular TypeScript Code角打字稿代码

import * as CryptoJS from 'crypto-js';
 
 encrypt(plainText: string): string {    
let cipherPhrase = environment.angularCipherKeyIvPhrase;
// separate the key and Iv from the cipher phrase string

var key = CryptoJS.enc.Utf8.parse(cipherPhrase.split("|")[0]);
var iv = CryptoJS.enc.Utf8.parse(cipherPhrase.split("|")[1]);

var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(plainText), key,
  {
    keySize: 128 / 8,
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });
console.log(encrypted.toString());
return encrypted;
  }

Decrypt Typescript Function解密打字稿功能

decrypt(encryptedText: string): string {

let cipherPhrase = environment.angularCipherKeyIvPhrase;

// separate the key and Iv from the cipher phrase string
var key = CryptoJS.enc.Utf8.parse(cipherPhrase.split("|")[0]);
var iv = CryptoJS.enc.Utf8.parse(cipherPhrase.split("|")[1]);

var decrypted = CryptoJS.AES.decrypt(encryptedText, key,
  {
    keySize: 128 / 8,
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });

return decrypted.toString(CryptoJS.enc.Utf8);
}

C# function to encrypt / decrypt C#函数加密/解密

        // encryption function similar to Angular cryptoJs
    public static string NgEncrypt(string plainText, string ngCipherKeyIvPhrase)
    {
        var cipherTextArray = ngCipherKeyIvPhrase.Split("|");
        string cipherPhrase = cipherTextArray[0];
        string salt  = cipherTextArray[1];

        byte[] encrypted;
        // Create a RijndaelManaged object  
        // with the specified key and IV.  
        using (var rijAlg = new RijndaelManaged())
        {
            rijAlg.Mode = CipherMode.CBC;
            rijAlg.Padding = PaddingMode.PKCS7;
            rijAlg.FeedbackSize = 128;

            rijAlg.Key = Encoding.UTF8.GetBytes(cipherPhrase);
            rijAlg.IV = Encoding.UTF8.GetBytes(salt);

            // Create a decrytor to perform the stream transform.  
            var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for encryption.  
            using (var msEncrypt = new MemoryStream())
            {
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        //Write all data to the stream.  
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        // Return the encrypted bytes from the memory stream.  
        return Convert.ToBase64String(encrypted);
    }

    // decryption function similar to Angular cryptoJs
    public static string NgDecrypt(string encryptedText,string ngCipherKeyIvPhrase)
    {
        string plainText = string.Empty;
        var cipherTextArray = ngCipherKeyIvPhrase.Split("|");
        string cipherPhrase = cipherTextArray[0];
        string salt = cipherTextArray[1];

        byte[] cipherText = Convert.FromBase64String(encryptedText); 
        // Create an RijndaelManaged object  
        // with the specified key and IV.  
        using (var rijAlg = new RijndaelManaged())
        {
            //Settings  
            rijAlg.Mode = CipherMode.CBC;
            rijAlg.Padding = PaddingMode.PKCS7;
            rijAlg.FeedbackSize = 128;

            rijAlg.Key = Encoding.UTF8.GetBytes(cipherPhrase);
            rijAlg.IV = Encoding.UTF8.GetBytes(salt);

            // Create a decryptor to perform the stream transform.  
            var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
            
                // Create the streams used for decryption.  
                using (var msDecrypt = new MemoryStream(cipherText))
                {
                    using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {

                        using (var srDecrypt = new StreamReader(csDecrypt))
                        {
                        // Read the decrypted bytes from the decrypting stream  
                        // and place them in a string.  
                        plainText = srDecrypt.ReadToEnd();

                        }

                    }
                }

                return plainText;
         
        }

    }

Encrypt data in c#加密c#中的数据

Refer https://www.c-sharpcorner.com/article/encryption-and-decryption-using-a-symmetric-key-in-c-sharp/ to encrypt data参考https://www.c-sharpcorner.com/article/encryption-and-decryption-using-a-symmetric-key-in-c-sharp/加密数据

Decrypt data in angular解密angular中的数据

Install crypto-js from https://www.npmjs.com/package/crypto-jshttps://www.npmjs.com/package/crypto-js安装 crypto-js

//install crypto-js from https://www.npmjs.com/package/crypto-js and import it   

import * as CryptoJS from 'crypto-js';

encrypedcode="Awt%2FgsVGXoQc3sasAkDqbVoXbXlmc2xZzu14cpHxmu1J0pvGYjGCm1uGz0qcpF07"

decryptData(encryptedText:any) {

    try {
      let cipherPhrase = 'decryptkey';

var key = CryptoJS.enc.Utf8.parse(cipherPhrase);
var iv = CryptoJS.enc.Utf8.parse('');

      var decrypted = CryptoJS.AES.decrypt(encryptedText.trim(), key,
        {
          keySize: 128/8,
          iv: iv,
          mode: CryptoJS.mode.CBC,
          padding: CryptoJS.pad.Pkcs7
        });

      return decrypted.toString(CryptoJS.enc.Utf8);


    } catch (e) {
      console.log(e);
    }
  }

 let data=this.decryptData(this.encrypedcode);
console.log(data);

For Encryption the basic idea is to对于加密,基本思想是

  • Use PBKDF2 for key generation.使用 PBKDF2 生成密钥。
  • Use AES cipher for encryption.使用 AES 密码进行加密。

You can read more about this encryption at : CrytoJs officialdocs您可以在以下位置阅读有关此加密的更多信息: CrytoJs 官方文档

Since Decryption is at server(C#) code we need to provide it with values such as- Salt,iv,encrypted text out of our cipher.由于解密是在服务器(C#)代码中,我们需要为它提供值,例如-Salt、iv、我们的密码中的加密文本。 To pass it we encode this all info in base64 string and pass it to server.为了传递它,我们将所有信息编码为 base64 字符串并将其传递给服务器。

For Encryption in Angular- (my project is in TS) If anyone has errors such as对于 Angular 中的加密-(我的项目在 TS 中)如果有人有错误,例如

  • "wordArray doesn't contain concat()" “wordArray 不包含 concat()”
  • Type 'WordArray' is not assignable to type 'string'类型 'WordArray' 不能分配给类型 'string'

I was able to go through few documentations and was able to find the solution to be able to combine salt, iv and cipher text.我能够浏览一些文档,并能够找到能够组合盐、iv 和密文的解决方案。

The issue was with Types we need to have a WordArray format of all these 3 to encode.问题在于类型,我们需要有所有这 3 种的 WordArray 格式来编码。

My approach is far-fetched but it works我的方法很牵强,但它有效

  • Convert all LIb.WordArray to ByteArray so its easy to combine all 3 strings to one.将所有 LIb.WordArray 转换为 ByteArray,以便将所有 3 个字符串合并为一个。
  • Before encoding to Base64 convert the combined to WordArray.在编码为 Base64 之前将组合转换为 WordArray。
  • Now Send this encoded string to Server for extracting the salt,iv,encryted text at server end to decrypt it.现在将此编码字符串发送到服务器以在服务器端提取盐,iv,加密文本以对其进行解密。

Make sure you have @types/crypto-js and crypto-js in your project.确保您的项目中有 @types/crypto-js 和 crypto-js。 My version("crypto-js": "^4.0.0", "@types/crypto-js": "^3.1.47").我的版本(“crypto-js”:“^4.0.0”,“@types/crypto-js”:“^3.1.47”)。

Encrytion At Angular side TypeScript : Angular 端 TypeScript 的加密

encrypt(msg: string) {
//will have this at C# as well.
var pass = "secret";
var keySize = 256;
//random salt
var salt = CryptoJS.lib.WordArray.random(16);
// to generate key
var key = CryptoJS.PBKDF2(pass, salt, {
  keySize: keySize / 32,
  iterations: 1000,
});
// random IV
var iv = CryptoJS.lib.WordArray.random(128 / 8);
//will attach link where you can find these
var encrypted = CryptoJS.AES.encrypt(msg, key, {
  iv: iv,
  padding: CryptoJS.pad.Pkcs7,
  mode: CryptoJS.mode.CBC,
});

//Convert Lib.WordArray to ByteArray so we can combine them like Concat
var saltwords = this.wordArrayToByteArray(salt);
var ivwords = this.wordArrayToByteArray(iv);
var cryptedText = this.wordArrayToByteArray(encrypted.ciphertext);
// combine everything together in ByteArray.
var header = saltwords.concat(ivwords).concat(cryptedText);
//Now convert to WordArray.
var headerWords = this.byteArrayToWordArray(header);
//Encode this to sent to server
var encodedString = CryptoJS.enc.Base64.stringify(headerWords);
return encodedString;  
}

Type Conversions :类型转换

wordArrayToByteArray(wordArray) {
if (
  wordArray.hasOwnProperty("sigBytes") &&
  wordArray.hasOwnProperty("words")
) {
  length = wordArray.sigBytes;
  wordArray = wordArray.words;
}

var result = [],
  bytes,
  i = 0;
while (length > 0) {
  bytes = this.wordToByteArray(wordArray[i], Math.min(4, length));
  length -= bytes.length;
  result.push(bytes);
  i++;
 }
 return [].concat.apply([], result);
 }
byteArrayToWordArray(ba) {
var wa = [],
  i;
for (i = 0; i < ba.length; i++) {
  wa[(i / 4) | 0] |= ba[i] << (24 - 8 * i);
}

return CryptoJS.lib.WordArray.create(wa);
}
wordToByteArray(word, length) {
 var ba = [],
  xFF = 0xff;
 if (length > 0) ba.push(word >>> 24);
 if (length > 1) ba.push((word >>> 16) & xFF);
 if (length > 2) ba.push((word >>> 8) & xFF);
 if (length > 3) ba.push(word & xFF);

return ba;
}

Decryption at C# is same as mentioned in answer given by EVK. C# 的解密与 EVK 给出的答案中提到的相同。

 public static string Decrypt(string cipherText)
    {
        var password = "secret";
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        using (Aes encryptor = Aes.Create())
        {
            // extract salt (first 16 bytes)
            var salt = cipherBytes.Take(16).ToArray();
            // extract iv (next 16 bytes)
            var iv = cipherBytes.Skip(16).Take(16).ToArray();
            // the rest is encrypted data
            var encrypted = cipherBytes.Skip(32).ToArray();
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, salt, 1000);
            encryptor.Key = pdb.GetBytes(32);
            encryptor.Padding = PaddingMode.PKCS7;
            encryptor.Mode = CipherMode.CBC;
            encryptor.IV = iv;

            using (MemoryStream ms = new MemoryStream(encrypted))
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Read))
                {
                    using (var reader = new StreamReader(cs, Encoding.UTF8))
                    {
                        return reader.ReadToEnd();
                    }
                }
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM