SHA1 из C # отличается от SHA1 в PHP [duplicate]

Если вы по какой-то причине хотите отделить действие создания и записи, эквивалент Java touch -

try {
   //create a file named "testfile.txt" in the current working directory
   File myFile = new File("testfile.txt");
   if ( myFile.createNewFile() ) {
      System.out.println("Success!");
   } else {
      System.out.println("Failure!");
   }
} catch ( IOException ioe ) { ioe.printStackTrace(); }

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

34
задан S.L. Barth 23 July 2012 в 08:36
поделиться

6 ответов

Используйте кодировку ASCIIEncoding вместо UnicodeEncoding. PHP использует кодировку ASCII для хэш-расчетов.

35
ответ дан Andrew Moore 21 August 2018 в 05:31
поделиться
  • 1
    Спасибо, это была проблема! – Anand Capur 26 April 2009 в 05:45
  • 2
    Поскольку кто-то удалил свой ответ ниже, UTF8Encoding также будет работать в вашем тестовом примере, но не будет работать, если у вас есть символы UTF8, такие как 艾. Правильная кодировка, используемая при работе с PHP IS ASCIIEncoding. – Andrew Moore 26 April 2009 в 05:49
  • 3
    Поскольку мне потребовалось некоторое время, чтобы узнать это: вход в хеш-функцию также должен быть преобразован в usig ASCII! И спасибо за ответы! Это просто здорово! – Mario The Spoon 17 December 2011 в 12:11
  • 4
    Стоит также отметить, что .NET использует Unicode по умолчанию, если вы не указали кодировку. – Hades 10 April 2013 в 11:06

FWIW, у меня была аналогичная проблема на Java. Оказалось, что мне пришлось использовать кодировку «UTF-8» для создания тех же SHA1-хэшей в Java, что и функция sha1, созданная в PHP 5.3.1 (работает на XAMPP Vista).

    private static String SHA1(final String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        final MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(text.getBytes("UTF-8"));
        return new String(org.apache.commons.codec.binary.Hex.encodeHex(md.digest()));
    }
1
ответ дан Gunnar 21 August 2018 в 05:31
поделиться

Была та же проблема. Этот код работал для меня:

string encode = secretkey + email;
SHA1 sha1 = SHA1CryptoServiceProvider.Create();
byte[] encodeBytes = Encoding.ASCII.GetBytes(encode);
byte[] encodeHashedBytes = sha1.ComputeHash(passwordBytes);
string pencodeHashed = BitConverter.
ToString(encode HashedBytes).Replace("-", "").ToLowerInvariant();
2
ответ дан nicojs 21 August 2018 в 05:31
поделиться

У меня тоже была эта проблема. Следующий код будет работать.

string dataString = "string to hash";
SHA1 hash = SHA1CryptoServiceProvider.Create();
byte[] plainTextBytes = Encoding.ASCII.GetBytes(dataString);
byte[] hashBytes = hash.ComputeHash(plainTextBytes);
string localChecksum = BitConverter.ToString(hashBytes)
.Replace("-", "").ToLowerInvariant();
5
ответ дан Paul Johnson 21 August 2018 в 05:31
поделиться
  • 1
    Почти это признало, что мне не хватало ToLowerInvariant. Благодаря!!! – AaronLS 11 July 2012 в 10:00

Попробуйте следующее! Я думаю, что он отлично поработает:

public static string SHA1Encodeb64(string toEncrypt)
    {
        //Produce an array of bytes which is the SHA1 hash
        byte[] sha1Signature = new byte[40];

        byte[] sha = System.Text.Encoding.Default.GetBytes(toEncrypt);
        SHA1 sha1 = SHA1Managed.Create();
        sha1Signature = sha1.ComputeHash(sha);


        /**
        * The BASE64 encoding standard's 6-bit alphabet, from RFC 1521,
        * plus the padding character at the end.
        */
        char[] Base64Chars = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
            'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
            'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
            'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
            'w', 'x', 'y', 'z', '0', '1', '2', '3',
            '4', '5', '6', '7', '8', '9', '+', '/',
            '='
            };
        //Algorithm to encode the SHA1 hash using Base64
        StringBuilder sb = new StringBuilder();
        int len = sha1Signature.Length;
        int i = 0;
        int ival;
        while (len >= 3)
        {
            ival = ((int)sha1Signature[i++] + 256) & 0xff;
            ival <<= 8;
            ival += ((int)sha1Signature[i++] + 256) & 0xff;
            ival <<= 8;
            ival += ((int)sha1Signature[i++] + 256) & 0xff;
            len -= 3;
            sb.Append(Base64Chars[(ival >> 18) & 63]);
            sb.Append(Base64Chars[(ival >> 12) & 63]);
            sb.Append(Base64Chars[(ival >> 6) & 63]);
            sb.Append(Base64Chars[ival & 63]);
        }
        switch (len)
        {
            case 0: // No pads needed.
                break;
            case 1: // Two more output bytes and two pads.
                ival = ((int)sha1Signature[i++] + 256) & 0xff;
                ival <<= 16;
                sb.Append(Base64Chars[(ival >> 18) & 63]);
                sb.Append(Base64Chars[(ival >> 12) & 63]);
                sb.Append(Base64Chars[64]);
                sb.Append(Base64Chars[64]);
                break;
            case 2: // Three more output bytes and one pad.
                ival = ((int)sha1Signature[i++] + 256) & 0xff;
                ival <<= 8;
                ival += ((int)sha1Signature[i] + 256) & 0xff;
                ival <<= 8;
                sb.Append(Base64Chars[(ival >> 18) & 63]);
                sb.Append(Base64Chars[(ival >> 12) & 63]);
                sb.Append(Base64Chars[(ival >> 6) & 63]);
                sb.Append(Base64Chars[64]);
                break;
        }
        //Encode the signature using Base64
        string base64Sha1Signature = sb.ToString();
        return base64Sha1Signature;
    }
-1
ответ дан shanethehat 21 August 2018 в 05:31
поделиться
  • 1
    использование System.Text.Encoding.Default является плохой идеей очень при работе со строками и криптографией. Различные платформы используют разные значения по умолчанию (UTF8, ASCII, Unicode), а использование Default просто делает его еще более сложным (поскольку оно может меняться между системами, конфигурацией и версиями). – poupou 21 February 2012 в 17:56
  • 2
    В .NET есть кодировщик Base64. Также я вижу byte[] sha1Signature = new byte[40];, а затем sha1Signature = sha1.ComputeHash(sha);. Вам не нужно new byte[40]. – quantum 27 October 2012 в 02:52

Этот метод в .NET эквивалентен sha1 в php:

string sha1Hash(string password)
{
    return string.Join("", SHA1CryptoServiceProvider.Create().ComputeHash(Encoding.UTF8.GetBytes(password)).Select(x => x.ToString("x2")));
}
9
ответ дан thorn 21 August 2018 в 05:31
поделиться
  • 1
    Просто любопытно: почему string.Join? – Spontifixus 20 September 2012 в 15:31
  • 2
    Метод Select (...) выводит массив строк, каждый из которых представляет один байт из байтов, возвращаемых методом ComputeHash (), эти строки должны объединяться один за другим. Метод join имеет этот прототип: String.Join (разделитель строк, значение params string []), см. ( msdn.microsoft.com/en-us/library/57a79xd0.aspx ). – OmarElsherif 22 September 2012 в 22:43
  • 3
    Ahh ... не прокручивал направо, и, таким образом, не видел выбора. Забудьте об этом вопросе. ;) – Spontifixus 24 September 2012 в 08:27
Другие вопросы по тегам:

Похожие вопросы: