在 dart 中使用 hmac 和 sha256 签署消息
Signing a message with hmac and sha256 in dart
我尝试使用消息上的 base64 解码密钥生成 sha256 HMAC。我想使用飞镖语言。在 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')
这是我用 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?
但是我不知道如何继续下去。我发现了一些旧的示例代码,如下所示
var message_byte = UTF8.encode(message);
hmac.add(message_byte);
然而,方法 "add" 在 Hmac class 中不再存在。这个我也试过了,不知道对不对
var message_byte = UTF8.encode(message);
var signature = hmac.convert(message_byte);
var signature_b64 = BASE64.encode(signature.bytes);
有人可以帮我吗?
如果您有整个 'message' 可用,那么只需调用 convert()。如果消息很大或成块,则分块处理。
你的例子很简单,一步一步讲出来。
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);
请阅读 Effective Dart 指南。注意常量现在是小写的,Dart 中的变量使用驼峰式等等
我不得不与 hmac 签署请求,以便在我最近的项目中调用 API。这是我所做的。希望这对你也有帮助。
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;
}
我尝试使用消息上的 base64 解码密钥生成 sha256 HMAC。我想使用飞镖语言。在 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')
这是我用 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?
但是我不知道如何继续下去。我发现了一些旧的示例代码,如下所示
var message_byte = UTF8.encode(message);
hmac.add(message_byte);
然而,方法 "add" 在 Hmac class 中不再存在。这个我也试过了,不知道对不对
var message_byte = UTF8.encode(message);
var signature = hmac.convert(message_byte);
var signature_b64 = BASE64.encode(signature.bytes);
有人可以帮我吗?
如果您有整个 'message' 可用,那么只需调用 convert()。如果消息很大或成块,则分块处理。
你的例子很简单,一步一步讲出来。
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);
请阅读 Effective Dart 指南。注意常量现在是小写的,Dart 中的变量使用驼峰式等等
我不得不与 hmac 签署请求,以便在我最近的项目中调用 API。这是我所做的。希望这对你也有帮助。
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;
}