2016-11-15 3 views
2

아직 암호를 연구 중입니다. C#에서 문자열을 DES (Base64 출력)로 암호화하는 간단한 정적 함수를 만들려고합니다. DES는 8 바이트를 키로 사용한다는 것을 알게되었습니다. 사용자가 원하는 길이의 문자열을 입력하고 키를 사용하여 메시지를 암호화 한 다음 Base64로 변환해야합니다. 예를 들어 site에 있습니다.사용자 입력 암호로 DES로 암호화

public static string EncryptDES(string phrase, string key) 
{ 
    string encrypted = ""; 

    byte[] phraseBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(phrase); 
    byte[] keyBytes = System.Text.Encoding.UTF8.GetBytes(key); 

    System.Security.Cryptography.MD5CryptoServiceProvider hashMD5Provider 
           = new System.Security.Cryptography.MD5CryptoServiceProvider(); 
    System.Security.Cryptography.DESCryptoServiceProvider provider 
           = new System.Security.Cryptography.DESCryptoServiceProvider(); 

    provider.Mode = System.Security.Cryptography.CipherMode.CBC; 

    System.Security.Cryptography.ICryptoTransform transform 
           = provider.CreateEncryptor(keyBytes, keyBytes); 
    System.Security.Cryptography.CryptoStreamMode mode 
           = System.Security.Cryptography.CryptoStreamMode.Write; 



    System.IO.MemoryStream memStream = new System.IO.MemoryStream(); 
    System.Security.Cryptography.CryptoStream cryptoStream 
           = new System.Security.Cryptography.CryptoStream(memStream, transform, mode); 
    cryptoStream.Write(phraseBytes, 0, phraseBytes.Length); 
    cryptoStream.FlushFinalBlock(); 

    byte[] encryptedMessageBytes = new byte[memStream.Length]; 
    memStream.Position = 0; 
    memStream.Read(encryptedMessageBytes, 0, encryptedMessageBytes.Length); 

    encrypted = System.Convert.ToBase64String(encryptedMessageBytes); 

    return (encrypted); 
} // private static string EncryptDES(string phrase, string key) { } 

다음 홈페이지에서 다음과 같이 호출 :

SimpleEncryption.EncryptDES("A message regarding some secure 512-bit encryption", "AnUltimatelyVeryVeryLongPassword"); 

을 (보다 크거나 8 자 미만 여부) 사용자가 문자열 길이의 임의의 숫자를 입력하면, 암호화 예외가 항상에서 발생 라인 :

System.Security.Cryptography.ICryptoTransform transform = provider.CreateEncryptor(keyBytes, keyBytes); 

그것은 Specified key is not a valid size for this algorithm.

벗기는 말한다 8 문자 (해싱의 유무에 관계없이)의 길이에 맞도록 키의 g 부분은 안전한 솔루션으로 보이지 않습니다 (높은 충돌 속도가있을 수 있습니다).

사용자 입력 문자열을 사용하여 DES (3DES 아님)를 구현하려면 어떻게해야합니까?

+0

'LegalKeySizes' 속성을 살펴 보았습니까? https://msdn.microsoft.com/en-us/library/system.security.cryptography.symmetricalgorithm.legalkeysizes(v=vs.110).aspx – McNets

+0

예. DES에서 64 비트 길이의 키를 사용하는 것을 알고 있지만 문자열을 암호화하는 데 사용 된 키와 일치하도록 사용자 입력 암호를 ​​맞추려면 어떻게해야합니까? –

+0

DESCryptoServiceProvider des = 새 DESCryptoServiceProvider(); Console.WriteLine ("DESCryptoServiceProvider"); ks = des.LegalKeySizes; foreach (키 크기 k in k) { Console.WriteLine ("\ t 최소 최소 키 크기 ="+ k.MinSize); Console.WriteLine ("\ tLegal max key size ="+ k.MaxSize); } – McNets

답변

0

사용자의 암호에서 해시를 생성하고 키로 사용하려면 8 바이트 만 가져야합니다.

var fullHash = hashMD5Provider.ComputeHash(System.Text.Encoding.ASCII.GetBytes(key)); 
var keyBytes = new byte[8]; 
Array.Copy(fullHash , keyBytes, 8); 

당신의 질문은 해시 충돌이 해시의 일부를 버리는 것에 대한 우려를 표명했습니다. 예, 확실히 위험은 증가하지만 (해시 알고리즘이 좋다고 가정하면) 해시 알고리즘을 사용하여 8 바이트 만 생성 한 것보다 더 나 빠지지는 않습니다. 좋은 해시 알고리즘은 엔트로피를 고르게 분배해야합니다.

+1

MD5는 매우 약한 키 유도 함수이므로 프로덕션 용도로 적합하지 않습니다. 대신 HMAC를 무작위로 약 100ms의 지속 시간 동안 반복하고 소금을 해시로 저장하십시오. 'PBKDF2','password_hash','Bcrypt' 등의 함수를 사용하십시오. 요점은 공격자가 무차별 적으로 암호를 찾는 데 많은 시간을 소비하게하는 것입니다. 사용자를 보호하는 것이 중요하므로 안전한 비밀번호 방법을 사용하십시오. – zaph

+0

@zaph OP는 이미 게시 된 코드에서 MD5 해시 알고리즘을 사용하고있었습니다. 나는 해시 알고리즘을 선택하지 않고 최소한의 코드 만 작동 시키려고했다. – RogerN

+1

다리에서 뛰어 내리는 것을 돕는 것처럼? 아 잠깐, 그건 좋은 아이디어도 아니야. 여기에 OP 코드에 관한 것이 아니라 애플리케이션 사용자를 위험에 빠뜨리는 것입니다. – zaph