2013-04-29 3 views
0

을 사용하여 암호화 된 데이터의 암호를 해독합니다. 지금 도움을 필요로하는 문제가 있습니다.node.js를 사용하여 C#

나는 C#을 사용하여 일부 암호화를 수행합니다. 그런 다음 node.js를 사용하여 해독 할 필요가 있습니다. 하지만 난 그냥 내 C# 암호화 알고리즘을 기반으로 정확하게 할 수없는 것으로 나타났습니다. 너희들이 해결책이 있다면 나를 도와주세요. 누군가가 나에게 nodejs에 대한 동일한 기능을 제공 할 수있는 경우

public static string Encrypt(string text, String password, string salt, string hashAlgorithm, int passwordIterations, string initialVector, int keySize) 
{ 
    if (string.IsNullOrEmpty(text)) 
     return ""; 

    var initialVectorBytes = Encoding.ASCII.GetBytes(initialVector); 
    var saltValueBytes = Encoding.ASCII.GetBytes(salt); 
    var plainTextBytes = Encoding.UTF8.GetBytes(text); 
    var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations); 
    var keyBytes = derivedPassword.GetBytes(keySize/8); 
    var symmetricKey = new RijndaelManaged(); 
    symmetricKey.Mode = CipherMode.CBC; 
    byte[] cipherTextBytes = null; 
    using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes)) 
    { 
     using (var memStream = new MemoryStream()) 
     { 
      using (var cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write)) 
      { 
       cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 
       cryptoStream.FlushFinalBlock(); 
       cipherTextBytes = memStream.ToArray(); 
       memStream.Close(); 
       cryptoStream.Close(); 
      } 
     } 
    } 
    symmetricKey.Clear(); 
    return Convert.ToBase64String(cipherTextBytes); 
} 
public static string Decrypt(string text, String password, string salt, string hashAlgorithm, int passwordIterations, string initialVector, int keySize) 
{ 
    if (string.IsNullOrEmpty(text)) 
     return ""; 

    var initialVectorBytes = Encoding.ASCII.GetBytes(initialVector); 
    var saltValueBytes = Encoding.ASCII.GetBytes(salt); 
    var cipherTextBytes = Convert.FromBase64String(text); 
    var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations); 
    var keyBytes = derivedPassword.GetBytes(keySize/8); 
    var symmetricKey = new RijndaelManaged(); 
    symmetricKey.Mode = CipherMode.CBC; 
    var plainTextBytes = new byte[cipherTextBytes.Length]; 
    var byteCount = 0; 
    using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes)) 
    { 
     using (var memStream = new MemoryStream(cipherTextBytes)) 
     { 
      using (var cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read)) 
      { 

       byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); 
       memStream.Close(); 
       cryptoStream.Close(); 
      } 
     } 
    } 
    symmetricKey.Clear(); 
    return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);  
} 

, 그 정말 도움이 될 것입니다 :

여기 내 C# 암호화 코드입니다. 어쨌든,이 게시물을 읽어 주셔서 감사합니다.

+0

구문 강조 표시를 확인하십시오. 이것이 규칙을 따르고'UpperCase' 변수 이름을 사용하지 않아야하는 이유입니다. –

+1

너무 조심스럽게 @JonathonReinhart를 청소했다 :) –

+0

죄송합니다 얘들 아, 나는 확실히 다음 번에 청소를 할 것입니다. 내 코드를 청소 해 주셔서 감사합니다. – Zhe

답변

2

먼저 Node.js에서 PasswordDeriveBytes 함수를 사용합니다. 이것은 crypto.pbkdf2이다

// find algorithm from the available ciphers; see crypto.getCiphers() 
var decipher = crypto.createDecipheriv(/* algorithm */, key, initialVector); 

그런 다음 그것을 데이터를 공급하고 decipher.update decipher.final을 사용

// assumes HMAC-SHA1 
crypto.pbkdf2(password, salt, iterations, keySize/8, function(err, key) { 
    if(err) /* handle error */ 
    // ... 
}); 

다음하는 디 크립 터를 생성하도록 crypto.createDecipheriv를 사용한다. 그들은 해독 된 데이터의 일부를 반환합니다.

+0

나는 이것을 시도했다 :'crypto.암호 해독 = crypto.createDecipheriv ('aes-128-cbc', key, initialVector); var dec = decipher.update (암호, 소금, 반복, keySize/8, function (err, key)) { 텍스트, 'base64', 'utf8') + decipher.final ('utf8'); });'작동하지 않고 C#에서 사용했지만 "Node"가 아닌 "hashAlgorithm"이 있음을 발견했습니다. 다른하실 말씀 있나요? – Zhe

+0

@Zhe : PBKDF2의 경우 Node.js는 HMAC-SHA1 만 지원합니다. – icktoofay

0

내가 Rfc2898DeriveBytes로 대체 PasswordDeriveBytes 위에서 @icktoofay, 하지만에 의해 제공되는 코드를 사용하여 성공적으로 "C#을 암호화 => 노드 해독"에 솔루션을 얻을 수 있었다 동일한 시나리오를 갖는

내 코드는 대략 다음과 같습니다

C#을

private byte[] saltBytes = ASCIIEncoding.ASCII.GetBytes(salt); 

public string Encrypt<T>(string value, string password) where T: SymmetricAlgorithm, new() { 
    byte[] valueBytes = UTF8Encoding.UTF8.GetBytes(value); 

    byte[] encrypted = null; 
    using (T cipher = new T()) { 
    var db = new Rfc2898DeriveBytes(password, saltBytes); 
    db.IterationCount = iterationsConst; 
    var key = db.GetBytes(keySizeConst/8); 

    cipher.Mode = CipherMode.CBC; 

    using (ICryptoTransform encryptor = cipher.CreateEncryptor(key, vectorBytes)) { 
     using (MemoryStream ms = new MemoryStream()) { 
     using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) { 
      cs.Write(valueBytes, 0, valueBytes.Length); 
      cs.FlushFinalBlock(); 
      encrypted = ms.ToArray(); 
     } 
     } 
    } 
    cipher.Clear(); 
    } 
    return Convert.ToBase64String(encrypted); 
} 

JavaScript :

var crypto = require('crypto'); 
var base64 = require('base64-js'); 
var algorithm = 'AES-256-CBC'; 

[...] 

var saltBuffer = new Buffer(salt); 
var passwordBuffer = new Buffer(password); 

[...] 

var encodedBuffer = new Buffer(base64.toByteArray(encryptedStringBase64Encoded)); 

crypto.pbkdf2(passwordBuffer, saltBuffer, iterations, keySize/8, function(err, key) { 
    var decipher = crypto.createDecipheriv(algorithm, key, iv); 
    var dec = Buffer.concat([decipher.update(encodedBuffer), decipher.final()]); 
    return dec; 
}); 

실제로 인터넷에서 발견 된 몇 가지 예가 결합 된 것입니다.

일부 특정 경우 (인코딩 된 문자열의 시작 부분에 '+'기호)의 Buffer 구현에 문제가있어서 https://github.com/beatgammit/base64-js의 base64-j을 사용했는데 정상적으로 작동하는 것 같습니다.