2013-12-20 121 views
2

我見過的C#代碼,可以加密,後來解密,使用這樣的代碼密碼:JavaScript中Rfc2898DeriveBytes的等價物?

http://wp7-travel.googlecode.com/svn/trunk/SilverlightPhoneDatabase/Cryptography.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Security.Cryptography; 
using System.IO; 
using System.Reflection; 

namespace SilverlightPhoneDatabase 
{ 
    /// <summary> 
    /// Class used to encrypt the database 
    /// </summary> 
    public static class Cryptography 
    { 

     /// <summary> 
     /// Incrypt the input using password provided 
     /// </summary> 
     /// <param name="input">Input string to encrypt</param> 
     /// <param name="password">Password to use</param> 
     /// <returns>Encrypted string</returns> 
     public static string Encrypt(string input, string password) 
     { 

      string data = input; 
      byte[] utfdata = UTF8Encoding.UTF8.GetBytes(data); 
      byte[] saltBytes = UTF8Encoding.UTF8.GetBytes(password); 



      // Our symmetric encryption algorithm 
      AesManaged aes = new AesManaged(); 

      // We're using the PBKDF2 standard for password-based key generation 
      Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes); 

      // Setting our parameters 
      aes.BlockSize = aes.LegalBlockSizes[0].MaxSize; 
      aes.KeySize = aes.LegalKeySizes[0].MaxSize; 
      aes.Key = rfc.GetBytes(aes.KeySize/8); 
      aes.IV = rfc.GetBytes(aes.BlockSize/8); 

      // Encryption 
      ICryptoTransform encryptTransf = aes.CreateEncryptor(); 

      // Output stream, can be also a FileStream 
      MemoryStream encryptStream = new MemoryStream(); 
      CryptoStream encryptor = new CryptoStream(encryptStream, encryptTransf, CryptoStreamMode.Write); 

      encryptor.Write(utfdata, 0, utfdata.Length); 
      encryptor.Flush(); 
      encryptor.Close(); 

      byte[] encryptBytes = encryptStream.ToArray(); 
      string encryptedString = Convert.ToBase64String(encryptBytes); 

      return encryptedString; 
     } 

     /// <summary> 
     /// Decrypt string using password provided 
     /// </summary> 
     /// <param name="base64Input">Input to decrypt</param> 
     /// <param name="password">Password to use</param> 
     /// <returns>Decrypted string</returns> 
     public static string Decrypt(string base64Input, string password) 
     { 

      byte[] encryptBytes = Convert.FromBase64String(base64Input); 
      byte[] saltBytes = Encoding.UTF8.GetBytes(password); 

      // Our symmetric encryption algorithm 
      AesManaged aes = new AesManaged(); 

      // We're using the PBKDF2 standard for password-based key generation 
      Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(password, saltBytes); 

      // Setting our parameters 
      aes.BlockSize = aes.LegalBlockSizes[0].MaxSize; 
      aes.KeySize = aes.LegalKeySizes[0].MaxSize; 
      aes.Key = rfc.GetBytes(aes.KeySize/8); 
      aes.IV = rfc.GetBytes(aes.BlockSize/8); 

      // Now, decryption 
      ICryptoTransform decryptTrans = aes.CreateDecryptor(); 

      // Output stream, can be also a FileStream 
      MemoryStream decryptStream = new MemoryStream(); 
      CryptoStream decryptor = new CryptoStream(decryptStream, decryptTrans, CryptoStreamMode.Write); 

      decryptor.Write(encryptBytes, 0, encryptBytes.Length); 
      decryptor.Flush(); 
      decryptor.Close(); 

      byte[] decryptBytes = decryptStream.ToArray(); 
      string decryptedString = UTF8Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length); 
      return decryptedString; 
     } 
    } 
} 

我不是安全專家,並與有限的加密算法的經驗。我有一個加密的密碼,通過這種代碼加密,現在想要訪問node.js程序(Javascript)中的解密密碼。

看來crypto-js有一個pbkdf2.js模塊,但它只知道如何加密密碼。我看過http://anandam.name/pbkdf2/,但它似乎又只是一個加密器。沒有解密。

任何人都可以提供密碼解密的代碼,給定一個已知的鹽和迭代,用於加密它,使用簡單的Javascript,最好利用普通模塊,如crypto-js

回答

3

PBKDF是基於密碼的密鑰導出函數。 PBKDF不是加密算法。可以將它們與一種使用salt的單向安全哈希算法進行比較(以使相同密碼的輸出獨一無二)和迭代計數(使其緩慢)。許多PBKDF,比如你問題中的PBKDF2,實際上是使用SHA-1等哈希算法實現的。

PBKDF函數通常用於生成密碼上的唯一標識符。該標識符將具有生成的密鑰材料的所有屬性,包括在沒有蠻力攻擊的情況下不可能檢索輸入材料的屬性。換句話說,你不能解密密碼 - 你只能嘗試每個可能的密碼來查看PBKDF2的輸出是否匹配。