【问题标题】:Common encrypt/decrypt code example for C# and Node.js/cryptoC# 和 Node.js/crypto 的常见加密/解密代码示例
【发布时间】:2012-11-03 05:59:09
【问题描述】:

我正在尝试使用 IIS 中的应用程序请求路由 (ARR) 将一组路径传递到 Node.js 网站。我的问题是能够在任一侧获取/设置身份验证票。

我真的只需要一个简单的加密/解密对示例,它可以在 C# 和 Node.js 上工作,并且开箱即用,并且两者的结果相同。在接下来的几天里,如果时间允许,我将自己解决这个问题,如果没有人在我之前提出答案,我打算回答。

我的意图是将节点端编写为 Node.js 端的连接/表达模块。我已经在 ASP.Net 解决方案中进行了自定义身份验证,并且可以轻松地将我当前的方法替换为可以在两个平台上都安全的方法(只要它们共享相同的密钥)。


AccountController.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);
}

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;
}

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>

【问题讨论】:

    标签: c# node.js express forms-authentication connect


    【解决方案1】:

    @xiaoyi 回答正确。另外,我只是添加了一些清晰的细节代码。

    在 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);
            }
    

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

    在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;
    }
    

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

    节点:new Buffer('', '') 已弃用。我将其替换为new Buffer.from()

    在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);
            }
    

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

    在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;
    }
    

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

    更多详情请关注DES algorithm

    【讨论】:

      【解决方案2】:

      这是一个使用 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));
          }
      }
      

      哪个输出

      iv: pdMBMjdeFdo=
      encrypted as: 3uDkdT6aQ3c=
      

      并在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);
      

      哪个输出

      3uDkdT6aQ3c= 3uDkdT6aQ3c=
      12345 12345
      

      【讨论】:

      • +1,如果你可以稍微重构一下,在 node.js 和 c# 中都有一个简单的加密和解密函数,它接受一个字符串并返回一个字符串,将标记答案正确。 :-)
      • @Tracker1 你问的太多了。 XD
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-26
      • 2018-11-24
      • 2010-10-13
      • 2014-11-10
      相关资源
      最近更新 更多