2012-05-07 2 views
-3

C#의 일반적인 DES 암호화에 문제가 있습니다. 16 문자 길이 (16 바이트 128 비트)의 출력 문자열에 영문자와 숫자 만 포함하면됩니다.128 비트 출력을 사용하는 DES 암호화

+1

출력 길이는 입력 길이 및 채우기 구성표의 함수입니다. 그런 다음 적절한 구성표로 출력을 인코딩 할 수 있지만 마지막 알파벳이 영숫자이면 일부 확장에 대처해야합니다. –

+0

입력 한 시간 (바이트)은 얼마입니까? @ GregS가 말했듯이, 여러분은 언제나 출력을 16 진수, Base-32 또는 Base-64로 인코딩 할 수 있습니다.하지만 인코딩은 항상 숫자 바이트보다 많을 것입니다. 또한이 길이와이 형식의 출력이 필요한 이유를 아는 데 도움이됩니다. – rossum

답변

1

영숫자로만 구성된 16 자 출력으로 제한되는 경우, ~ 95 비트의 출력 공간을 사용할 수 있음을 의미합니다 (Base-64 인코딩을 사용할 수있는 경우 정확히 96 비트, 즉 비영 문자 2 자 포함).

따라서이 제한 사항으로 95 비트를 초과하여 암호화 할 수있는 방법은 없습니다. 이것이 충분하면 가능합니다.

이와 비슷한 것 (CTR 모드의 3DES)은 (Base-64를 사용하여) 어떻게 작동 할 수 있었는지를 보여주는 예이지만 위에 언급 한 바와 같이 실제로 수행하려는 작업에 따라 달라집니다.

void Main() 
{ 
    var data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; 
    var key = new byte[] { 01, 12, 23, 34, 45, 56, 67, 78, 89, 90, 09, 98, 87, 76, 65, 54, 43, 32, 21, 10, 11, 22, 33, 44 }; 
    var encrypted = Encrypt(data, key, 0); 
    Console.WriteLine(encrypted); 
    var decrypted = Decrypt(encrypted, key, 0); 
    // decrypted should be equal to data here 
} 

public string Encrypt(byte[] data, byte[] key, long nonce) 
{ 
    return Convert.ToBase64String(Transform(data, key, nonce)); 
} 

public byte[] Decrypt(string data, byte[] key, long nonce) 
{ 
    return Transform(Convert.FromBase64String(data), key, nonce); 
} 

byte[] Transform(byte[] data, byte[] key, long nonce) 
{ 
    if (data.Length > 96/8) throw new ArgumentException("Too much data"); 

    using (var des = new TripleDESCryptoServiceProvider()) 
    { 
     des.Key = key; 
     des.Mode = CipherMode.ECB; 
     using (var encryptor = des.CreateEncryptor()) 
     { 
      var output = new byte[data.Length]; 
      var offset = 0; 
      for(int counter = 0; counter <= data.Length/8; ++counter) 
      { 
       var counterData = BitConverter.GetBytes(((long)counter)^nonce); 
       var counterEncryption = new byte[des.BlockSize/8]; 
       var counterEncryptionLen = encryptor.TransformBlock(counterData, 0, counterData.Length, counterEncryption, 0); 
       Debug.Assert(counterEncryptionLen == counterEncryption.Length); 
       for (var i = 0; i < des.BlockSize/8 && offset < output.Length; ++i, ++offset) 
       { 
        output[offset] = (byte)(data[offset]^counterEncryption[i]); 
       } 
      } 
      return output; 
     } 
    } 
} 
+0

감사합니다. @mormegil. 정말 도움이되었습니다. – Prime

관련 문제