Шифрование CryptoJS на C # SHA256

#xamarin.forms #tuya

#xamarin.forms #tuya

Вопрос:

я искал хорошее решение, в котором я скопировал код, используемый в API из postman, и попытался использовать его в формах Xamarin. Проблема в том, что в API есть метод, который генерирует «подписи», которые они делают в JS. Я пробовал различные решения, но он не генерирует одно и то же сообщение.

В JS =

 (function () { 
var timestamp = getTime();
pm.environment.set("timestamp",timestamp);
var clientId = pm.environment.get("client_id");
var secret = pm.environment.get("secret");
var sign = calcSign(clientId,secret,timestamp);
pm.environment.set('easy_sign', sign);
})();

function getTime(){
    var timestamp = new Date().getTime();
    return timestamp;
}

function calcSign(clientId,secret,timestamp){
    var str = clientId   timestamp;
    var hash = CryptoJS.HmacSHA256(str, secret);
    var hashInBase64 = hash.toString();
    var signUp = hashInBase64.toUpperCase();
    return signUp;
}
 

В C # =

 public void timeStamp()
    {
        /*
         *  var str = clientId   timestamp;
            var hash = CryptoJS.HmacSHA256(str, secret);
            var hashInBase64 = hash.toString();
            var signUp = hashInBase64.toUpperCase();
            return signUp;
        */

        var timestamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        var t = (DateTime.Now.ToUniversalTime() - timestamp);
        time = t.ToString();

        
        //CalcSign
        var str = clientID   t;
        var key = Convert.FromBase64String(secret);
        //var key = Convert.FromBase64String(str);
        Console.Write("key:");
        prtByte(key);

        var provider = new System.Security.Cryptography.HMACSHA256(key);
        var hash = provider.ComputeHash(Encoding.UTF8.GetBytes(str));
        Console.Write("hash:");
        prtByte(hash);

        var signature = Convert.ToBase64String(hash);
        Console.WriteLine("signature:"   signature);
        var signUp = signature.ToUpper();
        sign = signUp;
    }

    

    public static void prtByte(byte[] b)
    {
        for (var i = 0; i < b.Length; i  )
        {
            Console.Write(b[i].ToString("x2"));
        }
        Console.WriteLine();
    }
 

Сообщение, которое я получаю в ответ, =
«Время запроса недопустимо».

Комментарии:

1. вы сравнивали каждый элемент подписи в обеих средах, чтобы увидеть, какие конкретные из них не совпадают?

2. это time = t.ToString(); вернет совсем другое значение в C #, чем соответствующий код в JS.

3. Хм… как еще я могу добавить заголовок к запросу? (запрос. AddHeader(«t», «1607953974655»); Это должна быть строка, что мне делать, если проблема заключается здесь?

4. вам нужно правильно отформатировать строку времени — C # предоставляет широкий спектр хорошо документированных параметров форматирования, и я уверен, что есть много существующих вопросов, которые точно описывают, как форматировать дату C #, как это делает JS

5. google.com/…

Ответ №1:

После множества поисков и устранения неполадок и помощи от @Jason и @Jack Hua проблема была решена с помощью DateTime.UtcNow, форматирование строкой.Форматирование, преобразование значений сначала в double, а затем в int, как показано ниже.

 var timestamp = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
Console.WriteLine("Timestamp = " timestamp.ToString());
var t2 = String.Format("{0}",timestamp.TotalMilliseconds);     
var t = Double.Parse(t2);
var t3 = Convert.ToInt64(t);
time =""  t3;
 

Теперь мне нужно только решить мою другую проблему «sign invalid», но это другой вопрос. Приветствия!!

Комментарии:

1. Не забудьте отметить этот ответ позже, что поможет большему количеству людей с такой же проблемой :).