Смущенный, как я могу использовать ключ и подписать документ симметрично? - PullRequest
0 голосов
/ 18 января 2011

Я пытаюсь понять, как сделать ниже, в C #.

Написал пару раз об этом кажется очень запутанным.У меня есть документ XML, я хочу иметь возможность подписать документ симметрично и создать подпись в конце.

Первое:

Необходимо создать подпись, используя

1) данные в документе 2) уникальный ключ (слово или байтовый массив, который мы создаем)

А затем мне нужно написать программу, которая выдаст подпись, которую мы можем отправить вместе с документом, используя данные и ключ выше.

Секунда:

На другомВ завершение клиент запустит программу с уникальным ключом (ключ на шаге 2 выше), он посмотрит отправленную нами подпись.И тогда он сможет сказать, были ли данные подписаны с использованием этого ключа.Если данные изменились, то тест не пройден.Таким образом, мы знаем, что клиент не вмешивался в xml-файл.

ПРИМЕЧАНИЕ. Я понимаю, что это не очень безопасно, но пока нам достаточно.

Как это сделать?просто не могу понять основы шифрования: -)

Ответы [ 2 ]

2 голосов
/ 18 января 2011

вы должны взглянуть на MAC (коды аутентификации сообщений) https://secure.wikimedia.org/wikipedia/en/wiki/Message_authentication_code

Это не обязательно небезопасно. Проблема в том, что каждый, кто имеет ключ, может создать действительные подписи. Это означает, что каждый, кто должен иметь возможность проверять подписи, также может их создавать, и вы не можете определить, кто на самом деле подписал данные.

0 голосов
/ 19 января 2011

Для «довольно хорошей» безопасности я бы порекомендовал HMAC-SHA1 с ключом длиной не менее 160 бит (20 байтов).Для изучения более продвинутой криптографии я настоятельно рекомендую классическую книгу Шнайера Прикладная криптография .

. Для создания HMAC вы можете использовать удобный класс HMACSHA1 .

Например:

/// Pass in the xml text to sign, along with a hex or Base64-encoded, 160-bit secret key
public string GenerateSignature(string xml, string secretKey)
{
  using (HMACSHA1 encoder = new HMACSHA1(secretKey.ToAscii(), true))
  {
    return encoder.ComputeHash(xml.ToUtf8()).ToBase64();
  }
}

... используя следующие методы расширения:

public static byte[] ToUtf8(this string str)
{
  return Encoding.UTF8.GetBytes(str);
}

public static byte[] ToAscii(this string str)
{
  return Encoding.ASCII.GetBytes(str);
}

public static string ToBase64(this byte[] bytes)
{
  return Convert.ToBase64String(bytes);
}

Чтобы сгенерировать секретный ключ, вы можете перейти к random.org (не полностью безопасный, но может быть достаточным для ваших нужд), или сделайте это программно следующим образом:

System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
byte[] key = new byte[20];

rng.GetBytes(key);
string secretKey = key.ToBase64()

Вот еще несколько методов расширения, которые вам могут пригодиться:

public static string ToHex(this byte[] bytes)
{
  char[] c = new char[bytes.Length * 2];

  byte b;

  for(int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx) 
  {
    b = ((byte)(bytes[bx] >> 4));
    c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);

    b = ((byte)(bytes[bx] & 0x0F));
    c[++cx]=(char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
  }

  return new string(c);
}

public static byte[] HexToBytes(this string str)
{
  if (str.Length == 0 || str.Length % 2 != 0)
    return new byte[0];

  byte[] buffer = new byte[str.Length / 2];
  char c;
  for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
  {
    // Convert first half of byte
    c = str[sx];
    buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0')) << 4);

    // Convert second half of byte
    c = str[++sx];
    buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0'));
  }

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