2017-02-23 10 views
2

나는 (당신은 복사하여 실행 https://dotnetfiddle.net/에 붙여 넣을 수 있습니다) 3DES ECB 를 사용하여 텍스트를 암호화하는 C# 코드를 변환하기 위해 노력하고있어NodeJS 3DES ECB 암호화하지 않습니다 동일한 C# 암호화

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

public class Program 
{ 
    public static void Main() 
    { 
     string toEncrypt = "testtext"; 
     string key = "testkey"; 
     bool useHashing = true; 
     byte[] keyArray; 
     byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); 

     System.Configuration.AppSettingsReader settingsReader = 
               new AppSettingsReader(); 

     key = string.IsNullOrEmpty(key) ? (string)settingsReader.GetValue("SecurityKey", typeof(String)) : key; 

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

      hashmd5.Clear(); 
     } 
     else 
     { 
      keyArray = UTF8Encoding.UTF8.GetBytes(key); 
     } 

     TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); 
     key = Convert.ToBase64String(keyArray, 0, keyArray.Length); 
     Console.WriteLine(key); 
     tdes.Key = keyArray; 
     tdes.Mode = CipherMode.ECB; 
     tdes.Padding = PaddingMode.PKCS7; 

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

     tdes.Clear(); 

     Console.Write(Convert.ToBase64String(resultArray, 0, resultArray.Length)); 
    } 
} 

출력 :

Ihs2jX9fWXhn9SWXHyj/dQ== <- md5 secret key 
wHL9J7vhm9LZI2W5DQJGKw== <- encrypt result 

그래서 나는 암호 사용 NodeJS에서 위의 코드를 다시 작성

const crypto = require('crypto'); 
const md5 = text => { 
    return crypto 
    .createHash('md5') 
    .update(text) 
    .digest('base64'); 
} 

const encrypt = (text, secretKey) => { 
    secretKey = md5(secretKey); 
    console.log(secretKey); 

    const cipher = crypto.createCipher('des-ede3', secretKey); 
    const encrypted = cipher.update(text, 'utf8', 'base64'); 

    return encrypted + cipher.final('base64'); 
}; 
const encrypted = encrypt('testtext', 'testkey'); 

console.log(encrypted); 

출력 :

Ihs2jX9fWXhn9SWXHyj/dQ== <- md5 secret key 
VNa9fDYgPus5IMhUZRI+jQ== <- encrypt result 

나는 문제가 3DES의 ECB를 사용하여 C# 및 NodeJS 암호화 방식에있다 생각합니다. NodeJS에서의 C# 코드 동작을 어떻게 재현 할 수 있습니까?

답변

1

좋아요, 그냥 https://www.npmjs.com/package/nod3des을 사용하여 C#과 동일한 동작을 복제하십시오. 이

https://github.com/4y0/nod3des/blob/master/index.js#L30

var CryptoJS = require('crypto-js'); 
var forge = require('node-forge'); 
var utf8  = require('utf8'); 

... 

_3DES.encrypt = function (key, text){ 

    key   = CryptoJS.MD5(utf8.encode(key)).toString(CryptoJS.enc.Latin1); 
    key   = key + key.substring(0, 8); 
    var cipher = forge.cipher.createCipher('3DES-ECB', forge.util.createBuffer(key)); 
    cipher.start({iv:''}); 
    cipher.update(forge.util.createBuffer(text, 'utf-8')); 
    cipher.finish(); 
    var encrypted = cipher.output; 
    return (forge.util.encode64(encrypted.getBytes())); 

} 
+0

* 작업 *을 완료 할 수 있었지만 실제로이 질문에 * 답변 * 답장합니까? – AakashM

+0

@AakashM 그래, 그렇지만 게시일로부터 2 일 이내에 내 답변을 수락 할 수 없습니다. 질문은 "C# 코드를 NodeJS로 변환하는"대신 "NodeJS에서 C#의 동작을 복제하는 방법"이라고 생각합니다. 질문을 업데이트하겠습니다. –

1

삼중 DES는 192 비트 키에 대해 정의 어떻게 작동하는지 혹시 궁금. MD5 해시는 128 비트만을 제공합니다. 잠재적 인 128 비트 키를 192 비트 키로 확장하는 여러 가지 방법이 있습니다. 우리는 128 비트의 키는 두 개의 64 비트 서브 키 K1 및 K2로 구성된다고 가정하면, C#을 다시 K2K1K1 이루어지는 192 비트 키를 생성한다. 여기

작동 코드입니다 : 당신이 crypto#createCipher 대신 crypto#createCipheriv을 사용하고 있었다

const crypto = require('crypto'); 
const md5 = text => { 
    return crypto 
    .createHash('md5') 
    .update(text) 
    .digest(); 
} 

const encrypt = (text, secretKey) => { 
    secretKey = md5(secretKey); 
    console.log(secretKey.toString('base64')); 
    secretKey = Buffer.concat([secretKey, secretKey.slice(0, 8)]); // properly expand 3DES key from 128 bit to 192 bit 

    const cipher = crypto.createCipheriv('des-ede3', secretKey, ''); 
    const encrypted = cipher.update(text, 'utf8', 'base64'); 

    return encrypted + cipher.final('base64'); 
}; 
const encrypted = encrypt('testtext', 'testkey'); 

console.log(encrypted); 

다른 문제. 전자는이 경우 원하지 않는 "키"를 추가로 해싱합니다.


다른 잠재적 인 문제 :

  • ECB mode를 사용하지 마십시오. 결정 론적이며 따라서 의미 론적으로 안전하지 않습니다. 최소한 CBC 또는 CTR과 같은 무작위 모드를 사용해야합니다. padding oracle attack과 같은 공격이 불가능하도록 암호문을 인증하는 것이 좋습니다. 이는 GCM 또는 EAX와 같은 인증 된 모드 또는 encrypt-then-MAC 구성표를 사용하여 수행 할 수 있습니다.

  • 요즘에는 트리플 DES를 사용하지 마십시오. 192 비트의 가장 큰 키 크기를 사용하는 경우에도 최상의 112 비트 보안 만 제공합니다. 더 짧은 키 크기가 사용되면 56 비트 또는 57 비트의 보안 만 제공합니다. AES는 더 빠르며 (프로세서는 특별한 AES-NI 명령 세트를 가짐) 가장 낮은 128 비트 키 크기로 더욱 안전합니다. 또한 3DES로 최대 암호문 크기에 실질적인 제한이 있습니다. Security comparison of 3DES and AES을 참조하십시오.

  • 사용자의 암호를 보호하기 위해 간단한 해시 함수를 사용하지 마십시오. PBKDF2, bcrypt, scrypt 및 Argon2와 같은 강력한 해싱 체계를 사용해야합니다. 높은 비용 요소/반복 횟수를 사용해야합니다. 하나의 반복이 적어도 100ms가 걸리도록 비용을 선택하는 것이 일반적입니다. 더보기 : How to securely hash passwords?

+0

ECB 모드에 관한 답변을 주셔서 감사합니다. 내 고용주 비즈니스 파트너의 요구 사항. 나는 그들에게 AES를 사용하라고 말했지만 ECB를 사용하여 내가 여기에 진술 할 수없는 이유를 선호한다. –