简体   繁体   English

C# 和 Node.js/crypto 的通用加密/解密代码示例

[英]Common encrypt/decrypt code example for C# and Node.js/crypto

I'm attempting to use Application Request Routing (ARR) in IIS for passing a set of paths to a Node.js website.我正在尝试在 IIS 中使用应用程序请求路由 (ARR) 将一组路径传递到 Node.js 网站。 My issue is being able to get/set the authentication ticket on either side.我的问题是能够在任一侧获取/设置身份验证票。

I just really need a simple example of an Encrypt/Decrypt pair that will work for C# and Node.js close to out of the box with the same results for both.我真的需要一个简单的加密/解密对示例,它适用于 C# 和 Node.js,几乎开箱即用,两者的结果相同。 I'll be working on this problem myself as time permits over the next few days, and intend to answer if nobody comes up with an answer before me.在接下来的几天里,如果时间允许,我将自己解决这个问题,如果没有人在我之前提出答案,我打算回答。

My intention is to write the node side as a connect/express module on the Node.js side.我的意图是将节点端编写为 Node.js 端的 connect/express 模块。 I am already doing a custom authentication in the ASP.Net solution, and can easily replace my current method with something that can be secure from both platforms (so long as they share the same key).我已经在 ASP.Net 解决方案中进行了自定义身份验证,并且可以轻松地将我当前的方法替换为可以在两个平台上都安全的方法(只要它们共享相同的密钥)。


Current code to create the authentication cookie in AccountController.csAccountController.cs创建身份验证 cookie 的当前代码

private void ProcessUserLogin(MyEntityModel db, SiteUser user, bool remember=false)
{
  var roles = String.Join("|", value:user.SiteRoles.Select(sr => sr.Name.ToLowerInvariant().Trim()).Distinct().ToArray());

  //update the laston record(s)
  user.UserAgent = Request.UserAgent;
  user.LastOn = DateTimeOffset.UtcNow;
  db.SaveChanges();

  // Create and tuck away the cookie
  var authTicket = new FormsAuthenticationTicket(
    1
    ,user.Username
    ,DateTime.Now
    ,DateTime.Now.AddDays(31) //max 31 days
    ,remember
    ,string.IsNullOrWhiteSpace(roles) ? "guest" : roles
  );
  var ticket = FormsAuthentication.Encrypt(authTicket);
  var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, ticket);
  if (remember) cookie.Expires = DateTime.Now.AddDays(8);
  Response.Cookies.Add(cookie);
}

Current code to read the authentication cookie in Global.asax.cs当前用于读取Global.asax.cs的身份验证 cookie 的代码

void Application_AuthenticateRequest(object sender, EventArgs args)
{
  HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
  if (authCookie == null) return;

  FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

  string[] roles = authTicket.UserData.Split(new Char[] { '|' });

  //create new generic identity, and corresponding principal...
  var g = new GenericIdentity(authTicket.Name);
  var up = new GenericPrincipal(g, roles);

  //set principal for current request & thread (app will handle transitions from here)
  Thread.CurrentPrincipal = Context.User = up;
}

Relevant portion of the Web.config Web.config相关部分

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <membership>
      <providers>
        <!-- Remove default provider(s), so custom override works -->
        <clear />
      </providers>
    </membership>
  </system.web>
</configuration>

Here is a work example using DES algorithm.这是一个使用 DES 算法的工作示例。 reference 参考

using System;
using System.Text;
using System.Security.Cryptography;

public class Test
{
    public static string Encrypt(string toEncrypt, string key, bool useHashing) 
    {     
        byte[] keyArray;     
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);      

        if (useHashing)     
        {         
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));     
        }     
        else
            keyArray = UTF8Encoding.UTF8.GetBytes(key);      

        var tdes = new TripleDESCryptoServiceProvider();
        tdes.Key = keyArray;     
        // tdes.Mode = CipherMode.CBC;  // which is default     
        // tdes.Padding = PaddingMode.PKCS7;  // which is default

        Console.WriteLine("iv: {0}", Convert.ToBase64String(tdes.IV));

        ICryptoTransform cTransform = tdes.CreateEncryptor();     
        byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0,
            toEncryptArray.Length);      
        return Convert.ToBase64String(resultArray, 0, resultArray.Length); 
    }  

    public static void Main()
    {
        Console.WriteLine("encrypted as: {0}", Encrypt("12345", "abcdefghijklmnop", false));
    }
}

which outputs哪个输出

iv: pdMBMjdeFdo=
encrypted as: 3uDkdT6aQ3c=

And use the right algorithm des-ede-cbc in node.js:并在 node.js 中使用正确的算法des-ede-cbc

var crypto = require('crypto');

var alg = 'des-ede-cbc';

var key = new Buffer('abcdefghijklmnop', 'utf-8');
var iv = new Buffer('pdMBMjdeFdo=', 'base64');

var encrypted = new Buffer('3uDkdT6aQ3c=', 'base64');
var source = '12345';

var cipher = crypto.createCipheriv(alg, key, iv);
var encoded = cipher.update(source, 'ascii', 'base64');
encoded += cipher.final('base64');

console.log(encoded, encrypted.toString('base64'));

var decipher = crypto.createDecipheriv(alg, key, iv);
var decoded = decipher.update(encrypted, 'binary', 'ascii');
decoded += decipher.final('ascii');

console.log(decoded, source);

which outputs哪个输出

3uDkdT6aQ3c= 3uDkdT6aQ3c=
12345 12345

@xiaoyi answer is correct. @xiaoyi 答案是正确的。 In addition, I am just added a bit clear details code.另外,我只是添加了一些清晰的细节代码。

Encryption with DES algorithm in C#用C#中的DES算法加密

  public static string EncryptTest(string toEncrypt, string key, bool useHashing)
        {
            byte[] keyArray;
            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
            byte[] initVectorBytes = Encoding.ASCII.GetBytes("$secure#");

            if (useHashing)
            {
                MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            }
            else
                keyArray = UTF8Encoding.UTF8.GetBytes(key);

            var tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = keyArray;
            tdes.Mode = CipherMode.CBC;  // which is default     
            tdes.Padding = PaddingMode.PKCS7;  // which is default
            tdes.IV = initVectorBytes;

            ICryptoTransform cTransform = tdes.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0,
                toEncryptArray.Length);
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

When EncryptTest("1234", "abcdefghijklmnop", false) Output: GD/JSd91ZnQ=EncryptTest("1234", "abcdefghijklmnop", false)输出: GD/JSd91ZnQ=

Encryption with DES algorithm in nodejs nodejs中用DES算法加密

var algorithm = 'des-ede-cbc';

function encryption(plainText) {

    var key = new Buffer.from("abcdefghijklmnop", 'utf-8');
    var iv = new Buffer.from("$secure#", "ascii");

    var cipher = crypto.createCipheriv(algorithm, key, iv);
    var encoded = cipher.update(plainText, 'ascii', 'base64');
    encoded += cipher.final('base64');

    console.log(encoded);

    return encoded;
}

When encryption("1234") output: GD/JSd91ZnQ= encryption("1234")输出: GD/JSd91ZnQ=

Node: new Buffer('', '') is deprecated.节点:不推荐使用new Buffer('', '') I replaced it with new Buffer.from()我用new Buffer.from()替换了它

Decryption with DES algorithm in C# C#中用DES算法解密

public static string DecryptTest(string cipherString, string key, bool useHashing)
        {
            byte[] keyArray;
            byte[] toEncryptArray = Convert.FromBase64String(cipherString);
            byte[] initVectorBytes = Encoding.ASCII.GetBytes("$secure#");

            if (useHashing)
            {
                MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            }
            else
                 keyArray = UTF8Encoding.UTF8.GetBytes(key);

            var tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = keyArray;
            tdes.Mode = CipherMode.CBC;  // which is default     
            tdes.Padding = PaddingMode.PKCS7;  // which is default
            tdes.IV = initVectorBytes;

            ICryptoTransform cTransform = tdes.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return UTF8Encoding.UTF8.GetString(resultArray);
        }

When DecryptTest("GD/JSd91ZnQ=", "abcdefghijklmnop", false) Output: 1234DecryptTest("GD/JSd91ZnQ=", "abcdefghijklmnop", false)输出: 1234

Decryption with DES algorithm in nodejs nodejs中用DES算法解密

var algorithm = 'des-ede-cbc';

function decryption(chipertext) {

   var key = new Buffer.from("abcdefghijklmnop", 'utf-8');
    var iv = new Buffer.from("$secure#", "ascii");
    var encrypted = new Buffer.from(chipertext, 'base64');

    var decipher = crypto.createDecipheriv(algorithm, key, iv);
    var decoded = decipher.update(encrypted, 'binary', 'ascii');
    decoded += decipher.final('ascii');

    console.log(decoded);

    return decoded;
}

When decryption("GD/JSd91ZnQ=") output: 1234 decryption("GD/JSd91ZnQ=")输出: 1234

More details on DES algorithm DES算法的更多细节

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

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