4개 답변
- 최신
- 최다 투표
- 가장 많은 댓글
0
I'm not able to reproduce any problem. I took your code and wrapped into a Lambda function like this and it returns true. Is there any more information you can give to help reproduce your issue.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
namespace LambdaHmacTest
{
public class Function
{
public bool FunctionHandler(ILambdaContext context)
{
var password = "foobar";
var challenge = "this is a test";
var hmac = GenerateHMAC(password, challenge);
context.Logger.LogLine($"Password: {password}, Challenge: {challenge}, Hmac: {hmac}");
var validate = ValidateHMAC(password, challenge, hmac);
context.Logger.LogLine($"IsValid: {validate}");
return validate;
}
private static string GenerateHMAC(string password, string challenge)
{
HMACSHA256 hmc = new HMACSHA256(Encoding.UTF8.GetBytes(password));
byte[] hmres = hmc.ComputeHash(Encoding.UTF8.GetBytes(challenge));
string hmac = ByteToString(hmres);//
Console.WriteLine(hmac);
return hmac;
}
private static bool ValidateHMAC(string password, string challenge, string suppliedHMAC)
{
HMACSHA256 hmc = new HMACSHA256(Encoding.UTF8.GetBytes(password));
byte[] hmres = hmc.ComputeHash(Encoding.UTF8.GetBytes(challenge));
string hmac = ByteToString(hmres);//
Console.WriteLine(hmac);
if (suppliedHMAC == hmac)
return true;
else
return false;
}
public static string ByteToString(byte[] buff)
{
string sbinary = "";
for (int i = 0; i < buff.Length; i++)
{
sbinary += buff[i].ToString("X2"); // hex format
}
return (sbinary);
}
}
}
답변함 5년 전
0
Generate the HMAC on a client, pass the string to the Lambda endpoint (UTF8), then try to recreate the HMAC. I am getting different bytes, hence a different HMAC.
답변함 5년 전
0
This is the code I use to generate the token client side. When the HMAC is validated in the Lambda, it will fail. If I do it locally, it works fine.
private static bool TestUnit()
{
Console.WriteLine("Beginning test of endpoint ");
string url = "replace with endpoint url";
MyRequest mr = new MyRequest();
cr.Role = Roles.Unit; //0 indexed enum
cr.Timestamp = DateTime.UtcNow;
cr.UnitId = Guid.NewGuid();
cr.HMAC = GenerateHMAC(hmacSecret, cr.UnitId.ToString() + cr.Timestamp.ToString() + (int)cr.Role);
HttpClient client = new HttpClient();
//client.DefaultRequestHeaders.Add("x-api-key", "add api key");
string jsonObject = JsonConvert.SerializeObject(cr);
var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
try
{
var result = client.PostAsync(url, content).Result;
Console.WriteLine(result);
Console.WriteLine(result.Content.ReadAsStringAsync().Result);
Console.WriteLine();
Console.WriteLine("Ending test of endpoint Create");
return true;
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
[Serializable]
public enum Roles
{
Unit = 0,
SmallUnit,
BigUnit,
}
public class MyRequest
{
public string HMAC { get; set; }
public Roles Role { get; set; }
public Guid UnitId { get; set; }
public DateTime Timestamp { get; set; }
}
답변함 5년 전
0
I think I found the issue. The DateTime format is different between the client and server. Defining a format resolves the issue.
string format = "MMM ddd d HH:mm yyyy";
This can be passed as a variable to the .ToString(format) method of DateTime object.
답변함 5년 전