Twitter Arduino HMAC-SHA1的base64编码格式输出与JAVA/python/online工具不匹配
我正在从事一个Arduino项目,该项目需要基于OAuth 1.0的授权认证才能连接到云。这与[授权对Twitter API的请求][1]类似,我被困在[创建签名][2]的步骤中。创建签名的整个过程需要像encodeURL、base64encode和hmac-sha1这样的算法。在我的Arduino项目中,我对hmac-sha1使用Cryptosuite(链接3)库,对base64encode使用Arduino-base64(链接4)库。他们两人各自工作得很好。但是,我需要获得hmac-sha1的base64格式输出。所以我试过这个:Twitter Arduino HMAC-SHA1的base64编码格式输出与JAVA/python/online工具不匹配,twitter,oauth,arduino,Twitter,Oauth,Arduino,我正在从事一个Arduino项目,该项目需要基于OAuth 1.0的授权认证才能连接到云。这与[授权对Twitter API的请求][1]类似,我被困在[创建签名][2]的步骤中。创建签名的整个过程需要像encodeURL、base64encode和hmac-sha1这样的算法。在我的Arduino项目中,我对hmac-sha1使用Cryptosuite(链接3)库,对base64encode使用Arduino-base64(链接4)库。他们两人各自工作得很好。但是,我需要获得hmac-sha1
#include <avr/pgmspace.h>
#include <sha1.h>
#include <Base64.h>
uint8_t *in, out, i;
char b64[29];
static const char PROGMEM b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char key[] = "testKey";
char basestring[] = "testing";
void printHash(uint8_t* hash) {
int i;
for (i=0; i<20; i++) {
Serial.print("0123456789abcdef"[hash[i]>>4]);
Serial.print("0123456789abcdef"[hash[i]&0xf]);
}
Serial.println();
}
void setup() {
Serial.begin(115200);
Serial.print("Result:");
Sha1.initHmac((uint8_t*)key, strlen(key));
Sha1.print(basestring);
printHash(Sha1.resultHmac());
Serial.println();
// encoding
char* input;
input = (char*)(Sha1.resultHmac());
int inputLen = strlen(input);
int encodedLen = base64_enc_len(inputLen);
char encoded[encodedLen];
// note input is consumed in this step: it will be empty afterwards
base64_encode(encoded, input, inputLen);
Serial.print("base64 result: ");
Serial.println(encoded);
}
void loop() {
}
#包括
#包括
#包括
输入,输出,i;
char b64[29];
静态常量字符程序b64chars[]=“ABCDEFGHIJKLMNOPQRSTUVWXYZABCDFGHIJKLMNOPQRSTUVWXYZ0123456789+/”;
char key[]=“testKey”;
char basestring[]=“测试”;
无效打印哈希(uint8\u t*hash){
int i;
对于(i=0;i>4]);
Serial.print(“0123456789abcdef”[hash[i]&0xf]);
}
Serial.println();
}
无效设置(){
序列号开始(115200);
序列号。打印(“结果:”);
Sha1.initHmac((uint8_t*)键,strlen(键));
Sha1.打印(基线);
printHash(Sha1.resulthac());
Serial.println();
//编码
字符*输入;
输入=(char*)(Sha1.resultHmac());
int inputLen=strlen(输入);
int encodedLen=base64_enc_len(inputLen);
字符编码的[encodedLen];
//注:此步骤消耗输入:之后输入为空
base64_编码(编码、输入、输入);
Serial.print(“base64结果:”);
Serial.println(编码);
}
void循环(){
}
我得到的printHash的输出是60d41271d43b875b791e2d54c34bf3f018a29763,这与在线验证工具(链接5)完全相同。
但是,对于base64结果,我应该得到YNQScdQ7h1t5Hi1Uw0vz8Biil2M=的值。但我得到了L18B0HicKRhuxmB6SIFpZP+DpHxU,这似乎是错误的。我还尝试编写了一个JAVA程序和一个python程序,其中还提到base64结果的输出应该是YNQScdQ7h1t5Hi1Uw0vz8Biil2M=
我还发现了这篇文章:Arduino SHA1-HMAC与base64编码和Python之间的问题(链接6)。我还尝试了Adafruit推特收据中提到的tidy功能(链接7)
//base64编码SHA-1哈希输出。这不是通用base64
//编码器!它是为固定长度散列而精简的--总是20
//字节输入,总是27个字符输出+'='。
对于(in=Sha1.resultHmac(),out=0;in+=3){//八位字节到六位字节
b64[out++]=in[0]>>2;
b64[out++]=((in[0]&0x03)>4);
如果(输出>=26)中断;
b64[out++]=((in[1]&0x0f)>6);
b64[out++]=in[2]&0x3f;
}
b64[out]=(in[1]&0x0f)因此完整示例如下:
#include <avr/pgmspace.h>
#include <sha1.h>
#include <Base64.h>
char key[] = "testKey";
char basestring[] = "testing";
void printHash(uint8_t* hash) {
for (int i=0; i<20; i++) {
Serial.print("0123456789abcdef"[hash[i]>>4]);
Serial.print("0123456789abcdef"[hash[i]&0xf]);
}
Serial.println();
}
void setup() {
Serial.begin(115200);
Serial.print("Input: ");
Serial.println(basestring);
Serial.print("Key: ");
Serial.println(key);
Serial.print("Hmac-sha1 (hex): ");
Sha1.initHmac((uint8_t*)key, strlen(key));
Sha1.print(basestring);
uint8_t *hash;
hash = Sha1.resultHmac();
printHash(hash);
// base64 encoding
char* input = (char*) hash;
int inputLen = strlen(input) - 1; // skip null termination
int encodedLen = base64_enc_len(inputLen);
char encoded[encodedLen];
// note input is consumed in this step: it will be empty afterwards
base64_encode(encoded, input, inputLen);
Serial.print("Hmac-sha1 (base64): ");
Serial.println(encoded);
}
void loop() { }
因此,完整的示例将是:
#include <avr/pgmspace.h>
#include <sha1.h>
#include <Base64.h>
char key[] = "testKey";
char basestring[] = "testing";
void printHash(uint8_t* hash) {
for (int i=0; i<20; i++) {
Serial.print("0123456789abcdef"[hash[i]>>4]);
Serial.print("0123456789abcdef"[hash[i]&0xf]);
}
Serial.println();
}
void setup() {
Serial.begin(115200);
Serial.print("Input: ");
Serial.println(basestring);
Serial.print("Key: ");
Serial.println(key);
Serial.print("Hmac-sha1 (hex): ");
Sha1.initHmac((uint8_t*)key, strlen(key));
Sha1.print(basestring);
uint8_t *hash;
hash = Sha1.resultHmac();
printHash(hash);
// base64 encoding
char* input = (char*) hash;
int inputLen = strlen(input) - 1; // skip null termination
int encodedLen = base64_enc_len(inputLen);
char encoded[encodedLen];
// note input is consumed in this step: it will be empty afterwards
base64_encode(encoded, input, inputLen);
Serial.print("Hmac-sha1 (base64): ");
Serial.println(encoded);
}
void loop() { }
错误警报,我尝试访问Sha1.resultmac()两次。这使得sha结果不同。如果出现错误警报,我尝试访问Sha1.resultHmac()两次。这使得sha结果不同。
Input: testing
Key: testKey
Hmac-sha1 (hex): 60d41271d43b875b791e2d54c34bf3f018a29763
Hmac-sha1 (base64): YNQScdQ7h1t5Hi1Uw0vz8Biil2M=