[英]Getting "Uncaught ReferenceError: CryptoJS is not defined' in case of Encrypt in JavaScript and Decrypt in C# With AES Algorithm
[英]Encrypt in javascript and decrypt in C# with AES algorithm
我使用来自 AES 的CryptoJS.AES.encrypt()
方法对字符串进行了加密。
这是我的代码:
var txtloginKod = 'Some String...';
var key = CryptoJS.enc.Utf8.parse('8080808080808080');
var iv = CryptoJS.enc.Utf8.parse('8080808080808080');
var encryptedlogin = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(txtloginKod), key,
{
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
CryptoJS.AES.encrypt()
方法向我的encryptedlogin
变量返回一个对象。
我不知道如何在 C# 中将此对象发送到我的 WCF Web 服务器
当我尝试发送整个对象(并定义 Web 服务方法以期望获取 C# 对象)时,出现以下错误:
“将循环结构转换为 JSON”
我也需要将加密的 JSON 对象发送到 .Net CORE API 2.0 并在互联网上搜索以查找是否有任何帮助。 我知道现在你已经解决了这个问题,但为了帮助任何感兴趣的人,我提供了我的解决方案来帮助他们。
使用我在 stackoverflow 上找到的示例代码,我设法实现了该解决方案。 棘手的一点是关键,IV 的长度必须为 16,代码才能工作。
public static encrypt(model: any) {
const key = CryptoJS.enc.Utf8.parse('TestMyOwnKeyForI');
const iv = CryptoJS.enc.Utf8.parse('TestMyOwnIV1ForI');
// padding and truncating
const encryptedMessage = CryptoJS.AES.encrypt(JSON.stringify(model), key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString();
return encryptedMessage;
}
在 CORE 中,我实现了我的客户模型绑定提供程序,如下所示:
public class DecryptModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context.Metadata.ModelType == typeof(MyModel))
return new DecryptModelBinder();
return null;
}
}
然后我自己的decryptmodelbinder如下:
public class DecryptModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
throw new ArgumentNullException(nameof(bindingContext));
using (var sr = new StreamReader(bindingContext.HttpContext.Request.Body))
{
string valueFromBody = sr.ReadToEnd();
if (valueFromBody != null && valueFromBody.Length > 0)
{
var decrypted = Encryption.DecryptString(valueFromBody, "TestMyOwnKeyForI");
var model = JsonConvert.DeserializeObject(decrypted, bindingContext.ModelType);
bindingContext.Result = ModelBindingResult.Success(model);
bindingContext.Model = model;
}
}
return Task.CompletedTask;
}
}
使用 Dot net core 和 Type Script。
npm instal crypto-js
//Inside imports of your TS file include
import * as CryptoJS from 'crypto-js';
// Declare this key and iv values in declaration
private key = CryptoJS.enc.Utf8.parse('4512631236589784');
private iv = CryptoJS.enc.Utf8.parse('4512631236589784');
// Methods for the encrypt and decrypt Using AES
encryptUsingAES256() {
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(JSON.stringify("Your Json Object data or string")), this.key, {
keySize: 128 / 8,
iv: this.iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log('Encrypted :' + encrypted);
this.decryptUsingAES256(encrypted);
return encrypted;
}
decryptUsingAES256(decString) {
var decrypted = CryptoJS.AES.decrypt(decString, this.key, {
keySize: 128 / 8,
iv: this.iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log('Decrypted : ' + decrypted);
console.log('utf8 = ' + decrypted.toString(CryptoJS.enc.Utf8));
}
用于编码或解码的 C# 代码在这里。
public class encr {
public static string DecryptStringAES(string cipherText) {
var keybytes = Encoding.UTF8.GetBytes("4512631236589784");
var iv = Encoding.UTF8.GetBytes("4512631236589784");
var encrypted = Convert.FromBase64String(cipherText);
var decriptedFromJavascript = DecryptStringFromBytes(encrypted, keybytes, iv);
return decriptedFromJavascript;
}
private static string DecryptStringFromBytes(byte[] cipherText, byte[] key, byte[] iv) {
// Check arguments.
if (cipherText == null || cipherText.Length <= 0) {
throw new ArgumentNullException("cipherText");
}
if (key == null || key.Length <= 0) {
throw new ArgumentNullException("key");
}
if (iv == null || iv.Length <= 0) {
throw new ArgumentNullException("key");
}
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// 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 = key;
rijAlg.IV = iv;
// Create a decrytor to perform the stream transform.
var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
try {
// 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();
}
}
}
} catch {
plaintext = "keyError";
}
}
return plaintext;
}
public static string EncryptStringAES(string plainText) {
var keybytes = Encoding.UTF8.GetBytes("4512631236589784");
var iv = Encoding.UTF8.GetBytes("4512631236589784");
var encryoFromJavascript = EncryptStringToBytes(plainText, keybytes, iv);
return Convert.ToBase64String(encryoFromJavascript);
}
private static byte[] EncryptStringToBytes(string plainText, byte[] key, byte[] iv) {
// Check arguments.
if (plainText == null || plainText.Length <= 0) {
throw new ArgumentNullException("plainText");
}
if (key == null || key.Length <= 0) {
throw new ArgumentNullException("key");
}
if (iv == null || iv.Length <= 0) {
throw new ArgumentNullException("key");
}
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 = key;
rijAlg.IV = iv;
// 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 encrypted;
}
}
您需要自己序列化密文。 有很多方法可以做到。
如果密钥不是字符串,而是WordArray
(如您的情况),那么简单的encryptedlogin.toString()
将生成仅包含密文的 Base64 编码字符串。 请记住,您需要包含 enc-base64.js 源文件。
如果“密钥”(实际上是密码)是字符串,则应用与 OpenSSL 兼容的密钥派生。 在这种情况下, encryptedlogin.toString()
将是一个 Base64 编码的字符串,其中包含“Salted__”字符串、8 字节随机盐和密文。
如果你只想得到密文,那么encryptedlogin.ciphertext.toString()
会给你一个只包含密文的十六进制编码字符串, encryptedlogin.iv.toString()
会给你一个十六进制编码的 IV。 您可以通过这种方式生成 Base64 编码的字符串encryptedlogin.ciphertext.toString(CryptoJS.enc.Base64)
。
请记住,必须为每个加密随机选择 IV,以提供语义安全性。 它不必是秘密的,因此您可以将其与密文一起发送。
在服务器端,您将解码值(Base64 或 Hex,取决于您在加密期间使用的内容)并将它们与 AesCryptoServiceProvider 类(或类似类)一起使用来解密密文。
请记住,您还需要验证您的密文以检测(恶意)操作。 这可以通过具有强 MAC(如 HMAC-SHA256)的 encrypt-then-MAC 方案来完成。
此外,如果密钥与密文一起传输或通过不安全的通道传输,那么这基本上只是数据混淆,并不能提供真正的安全性。 查看更多: Javascript 密码学被认为是有害的
使用返回对象中的 encryptedLogin.cipherText
此外,您应该使用 CryptoJS v3.1.2 AES 实现来使用它。 你可以在这里下载: https : //storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/crypto-js/CryptoJS%20v3.1.2.zip
您可以在此处找到 Js 端代码:jsfiddle.net/aEKw5/22/
因此,使用上面的信息,您可以在 C# 端进行编码,并在 js 上对其进行解码。 反之亦然。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.