简体   繁体   English

在 dart 中使用 hmac 和 sha256 对消息进行签名

[英]Signing a message with hmac and sha256 in dart

I try to generate a sha256 HMAC using a base64-decoded secret key on a message.我尝试使用消息上的 base64 解码密钥生成 sha256 HMAC。 I would like to use the dart language.我想使用 dart 语言。 In python, I could do it with the following code:在 python 中,我可以使用以下代码来完成:

# PYTHON CODE
import hmac, hashlib, base64
...
message = 'blabla'
secret = 'DfeRt[...]=='
secret_b64 = base64.b64decode(secret)
signature = hmac.new(secret_b64, message, hashlib.sha256)
signature_b64 = signature.digest().encode('base64').rstrip('\n')

Here is what I tried with dart:这是我用 dart 尝试的结果:

// DART CODE
import 'package:crypto/crypto.dart';
import 'dart:convert';
...
String message = 'blabla';
String secret = 'DfeRt[...]=='
var secret_b64 = BASE64.decode(secret);
var hmac = new Hmac(sha256, secret_b64);
// what now?

But then I don't know how to go on.但是后来不知道go怎么上。 I found some old example code which looks like the following我发现了一些旧的示例代码,如下所示

var message_byte = UTF8.encode(message);
hmac.add(message_byte);

However, the method "add" does not exist any more in the Hmac class. I also tried this, but I am not sure if this is correct但是,Hmac class 中不再存在“add”方法。我也试过了,但我不确定这是否正确

var message_byte = UTF8.encode(message);    
var signature = hmac.convert(message_byte);
var signature_b64 = BASE64.encode(signature.bytes);

Can someone help me out?有人可以帮我吗?

If you have the whole 'message' available then just call convert().如果您有完整的“消息”可用,则只需调用 convert()。 If the message is large or in pieces then deal with it in chunks.如果消息很大或分块,则分块处理。

Your example is simple, when spelled out step by step.你的例子很简单,分步说明。

  String base64Key = 'DfeRt...';
  String message = 'blabla';

  List<int> messageBytes = utf8.encode(message);
  List<int> key = base64.decode(base64Key);
  Hmac hmac = new Hmac(sha256, key);
  Digest digest = hmac.convert(messageBytes);

  String base64Mac = base64.encode(digest.bytes);

Please read the Effective Dart guide.请阅读Effective Dart指南。 Note how constants are now lower case, variables in Dart use camel case, etc注意常量现在是小写的,Dart 中的变量使用驼峰大小写等

I had to sign a request with hmac for calling an API in my recent project.我必须用 hmac 签署一个请求,以便在我最近的项目中调用 API。 Here is what I had done.这是我所做的。 Hope this helps you too.希望这对你也有帮助。

import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:crypto/crypto.dart';

String getHmacAuthHeader({
  @required final String inputUrl,
  @required final dynamic inputJsonContent,
  @required final String appId,
  @required final String appSecrets,
  final String method = "POST",
}) {
  final url = _encodeUrl(inputUrl);
  final seconds =
      (DateTime.now().millisecondsSinceEpoch / 1000).round().toString();
  final nonce = "N${DateTime.now().millisecondsSinceEpoch}";

  final contentHash = _getMd5HashInBase64FromJson(inputJsonContent);

  final signature = "$appId$method$url$seconds$nonce$contentHash";

  final signatureHmacHashBase64 = _getHmacHashInBase64FromString(appSecrets, signature);

  final token = "$appId:$signatureHmacHashBase64:$nonce:$seconds";

  return "hmacauth $token";
}

String _encodeUrl(String url) {
  if (!url.startsWith("/")) {
    url = "/$url";
  }
  return Uri.encodeComponent(url).toLowerCase();
}

String _getMd5HashInBase64FromJson(dynamic json) {
  final jsonString = jsonEncode(json);
  final jsonStringBytes = Utf8Encoder().convert(jsonString);

  final hashBytes = md5.convert(jsonStringBytes).bytes;
  final hashBase64 = base64Encode(hashBytes);
  return hashBase64;
}

String _getHmacHashInBase64FromString(String key, String data){
  final keyBytes = Utf8Encoder().convert(key);
  final dataBytes = Utf8Encoder().convert(data);

  final hmacBytes = Hmac(sha256, keyBytes)
      .convert(dataBytes)
      .bytes;

  final hmacBase64 = base64Encode(hmacBytes);
  return hmacBase64;
}

Hey I'm late to Answer this question.嘿,我来晚了回答这个问题。 But I think anyone can use this Answer.但我认为任何人都可以使用这个答案。 I use https://pub.dev/packages/crypto package我使用https://pub.dev/packages/crypto package

For that you can use为此你可以使用

import 'dart:convert';
import 'package:crypto/crypto.dart';


message = 'blabla'
secret = 'DfeRt[...]=='

void main() {
  var key = utf8.encode(secret);
  var bytes = utf8.encode(message);

  var hmacSha256 = Hmac(sha256, key); // HMAC-SHA256
  var digest = hmacSha256.convert(bytes);

  print("HMAC digest as bytes: ${digest.bytes}");
  print("HMAC digest as hex string: $digest");
}

I think this will save codes and clean.我认为这将节省代码和清洁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM