Требуется решение для тройного шифрования DES с двумя ключами - PullRequest
0 голосов
/ 04 октября 2011

Возможно ли это в C #? Как мне это сделать?

Тройной DES с двумя ключами - это то, где мы шифруем с помощью K1, затем дешифруем с помощью K2 и, наконец, снова шифруем с помощью K1. Таким образом, пространство ключей составляет 2 x 56 = 112 бит.

Например, с K1=0x0123456789ABCDEF и K2=0xFEDCBA9876543210 вы бы задали тройной ключ DES равным 0x0123456789ABCDEFFEDCBA98765432100123456789ABCDEF.

0123456789ABCDEF FEDCBA9876543210 0123456789ABCDEF
|<------K1------>|<------K2------>|<------K3------>|

Он принимает A9993E364706816A и 2 ключа, которые он должен использовать, это K1 = 0123456789ABCDEF и K2 = FEDCBA9876543210. Конечный результат должен быть: 6E5271A3F3F5C418, который я не получаю.

UPDATE:

Я пытаюсь создать связанный ключ, который мне нужно использовать. Используемые выше 2 ключа преобразуются в байтовый массив и имеют длину по 16 для каждого. И когда 2 соединяются, тогда длина равна 32. Тогда мой код взрывается. Ключ должен иметь длину 16 или 24. Что мне нужно сделать в этом случае?

UTF8Encoding characterEncoding = new UTF8Encoding();
byte[] accessKey1ByteArray = characterEncoding.GetBytes(accessKey1);
byte[] accessKey2ByteArray = characterEncoding.GetBytes(accessKey2);
byte[] accessKeysArray = accessKey1ByteArray.Concat(accessKey2ByteArray).ToArray();

Здесь я пытаюсь установить свои значения:

public byte[] ComputeTripleDesEncryption(byte[] plainText, byte[] key)
{
     TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();

     des.Key = key;
     des.GenerateIV();
     des.Mode = CipherMode.ECB;
     des.Padding = PaddingMode.None;

     ICryptoTransform ic = des.CreateEncryptor();

     byte[] enc = ic.TransformFinalBlock(plainText, 0, plainText.Length);

     return enc;
}

ОБНОВЛЕНИЕ 2

Нужно ли устанавливать размер? Ключ байтового массива, через который я отправляю: K1 + K2 + K1.

Текст, который я отправляю, нужно ли мне преобразовать его в байты, как вы рекомендовали, или следующее тоже поможет?

UTF8Encoding characterEncoding = new UTF8Encoding();
byte[] block1ByteArray = characterEncoding.GetBytes(block1);

Значение block1: A9993E364706816A.

Как я получил A9993E364706816A из моего хэшированного результата SHA-1. Первые 16 символов этого хэшированного результата моей строки, которую я хочу кодировать.

Ответы [ 2 ]

2 голосов
/ 04 октября 2011

Для шифрования / дешифрования данных с помощью алгоритма TripleDES вы можете использовать TripleDESCryptoServiceProvider Class .Алгоритм поддерживает длину ключа от 128 до 192 бит с шагом 64 бита.

Если у вас есть два 64-битных ключа

byte[] k1 = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
byte[] k2 = new byte[] { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };

и вы хотите снова объединить k1, k2 и k1для 192-битного ключа вы можете сделать это следующим образом:

byte[] key = new byte[K1.Length + K2.Length + K1.Length];
Buffer.BlockCopy(k1, 0, result,  0, 8);
Buffer.BlockCopy(k2, 0, result,  8, 8);
Buffer.BlockCopy(k1, 0, result, 16, 8);

Обратите внимание, что в дополнение к ключу вам также необходим вектор инициализации:

byte[] iv = // ...

Пример:

byte[] data = new byte[] { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A };

using (var csp    = new TripleDESCryptoServiceProvider())
using (var enc    = csp.CreateEncryptor(key, iv))
using (var stream = new MemoryStream())
using (var crypto = new CryptoStream(stream, enc, CryptoStreamMode.Write))
{
    crypto.Write(data, 0, data.Length);
}
2 голосов
/ 04 октября 2011

Звучит так, будто вы просто хотите установить 128-битную клавишу для ключа тройного дес.

Я полагаю, что в этом случае, если вы предоставляете 128-битный ключ, он разделяет его на два 64-битных ключа и использует первый как K1 и K3, а второй как K2, что именно то, что вы хотите.

К сожалению, я не могу найти источник, чтобы процитировать это, но я недавно много читал на эту тему, когда сам реализовал некоторые криптографические вещи и узнал о длине ключей, и это то, что я обнаружил.

Если у вас уже есть K1 и K2 в качестве байтовых массивов, тогда вы можете просто использовать симпатичный метод расширения linq и выполнить:

SymmetricAlgorithm cryptoService = new TripleDESCryptoServiceProvider();
byte[] myKey = K1.Concat(K2).ToArray();
cryptoService.Key = mKey;

Это будет тогда делать, как вы хотите.

В ответ на вашу обновленную часть вопроса у вас есть два ключа - шестнадцатеричное представление последовательности байтов. 0x0123456789ABCDEF - это 16 шестнадцатеричных символов, но это эквивалентно 8 байтам информации, поскольку каждый символ содержит 4 бита - два составляют байт.

Чтобы преобразовать эту строку в байтовый массив, можно использовать следующую функцию:

public static byte[] StringToByteArray(String hex)
{
    if (hex.Substring(0,2)=="0x")
    hex = hex.Substring(2);
    int NumberChars = hex.Length;
    byte[] bytes = new byte[NumberChars / 2];
    for (int i = 0; i < NumberChars; i += 2)
        bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
    return bytes;
}

(из Как преобразовать массив байтов в шестнадцатеричную строку и наоборот? )

Это будет использоваться следующим образом:

string K1="0x0123456789ABCDEF";
string K2="0xFEDCBA9876543210";
byte[] key = StringToByteArray(K1).Concat(StringToByteArray(K2)).ToArray();

При реализации TDES вам нужно будет согласовать ключ, режим блочного шифра, метод заполнения, а в большинстве блочных режимов вам потребуется вектор инициализации. Возможно, вы также захотите использовать код аутентификации сообщения.

Чтобы получить вектор инициализации, вам нужно сделать что-то вроде:

cryptoService.GenerateIV();
byte[] iv = cryptoService.IV;

Я настоятельно советую читать страницы о шифровании, чтобы лучше понять, чем на самом деле являются различные вещи, а не просто писать код. Это сделает вас более уверенным в своей безопасности и заставит вас чувствовать себя более уверенно, общаясь с другими. Я позволил себе включить некоторые ссылки, большинство из которых можно найти, просто погуглив.

Полезные ссылки:

http://en.wikipedia.org/wiki/Initialization_vector - все о векторах инициализации

http://en.wikipedia.org/wiki/Triple_DES - по алгоритму TDES

http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation - Как последовательные блоки данных взаимодействуют друг с другом.

http://en.wikipedia.org/wiki/Padding_%28cryptography%29 - Не очень важно, за исключением того, что существуют разные способы заполнения, и обе стороны должны использовать один и тот же (конечно).

http://chargen.matasano.com/chargen/2009/7/22/if-youre-typing-the-letters-a-e-s-into-your-code-youre-doing.html - Отличный и забавный комментарий об использовании шифрования и о том, где есть недостатки и что шифрование может и не может делать.

http://en.wikipedia.org/wiki/Message_authentication_code - Как подтвердить, что ваше сообщение не было подделано

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...