我正在处理HMAC输入以获取签名的库,然后将在服务器上检查签名以验证发件人。我的问题是库和服务器生成不同的HMAC。我使用OpenSSL包提供的HMAC功能。
密钥是Secret and secure key!
,软件包(数据)是{"alg":"SHA256","id":1,"data":"DOGOOS","time":3,"expire":1}
,它生成以下签名egL2gFU2DZVNkTk7jzhl7YJOKhHOWqTh/pUi3G2G2C4=
,而我的服务器为相同的数据生成6DE3KUbbF6nKttaKIWRQaKAgdA7gG1JiPU63L1uPOww=
。
我还测试过使用以下设置从此网站https://www.liavaag.org/English/SHA-Generator/HMAC/生成签名,它会产生与我的服务器相同的结果。
Input type: Text
Key type: Text
Sha variant: SHA256
Output type: Base64
我已经确认Base64Encode功能正常工作。
unsigned char* sign(char* package, int package_len, char* key, int key_len, unsigned char* signature, unsigned int *signature_len, char** b64){
HMAC(EVP_sha256(), key, key_len, package, package_len, signature, signature_len);
Base64Encode(signature, *signature_len, b64);
return 0;
}
int main(int argc, const char * argv[]) {
int average = 3;
uint package_size = 100;
uint id = 1;
char *package = (char*)malloc(package_size * sizeof(char));
char *data = "DOGOOS";
format(&package, package_size, data, SHA256, id, average, 1);
unsigned char* key = "Secret and secure key!";
int key_len = 22;
uint signature_len = 200;
char* signature = (char*)malloc(signature_len * sizeof(char));
char* base64_output;
unsigned char* output = sign(package, package_size, key, key_len, signature, &signature_len, &base64_output);
printf("package: %s\n", package);
printf("SIGNATURE: %s\n", base64_output);
free(base64_output);
free(signature);
free(output);
free(package);
return 0;
}
根据要求,这是服务器端的代码。它是生锈的。我生成的结果与我所用的网站相同,因此对于我所做的所有测试,服务器都会生成正确的输出。
#[derive(Debug, Clone, Copy)]
pub enum Algorithm {
SHA256,
SHA512,
}
pub struct Packet{
algorithm: types::Algorithm,
payload: String,
signature: Vec<u8>,
start_time: u64,
timestamp: u64,
expire: u64,
}
impl Packet {
/**
* Returns the algorithm used.
*/
pub fn get_algorithm(&self) -> types::Algorithm {
self.algorithm.clone()
}
/**
* Returns the signature.
*/
pub fn get_signature(&self) -> &Vec<u8> {
&self.signature
}
pub fn get_payload(&self) -> String {
self.payload.clone()
}
}
/**
* Validates the signature of the packet
*/
fn validate_packet(packet: &packet::Packet, key: &str) -> bool{
let result = match packet.get_algorithm(){
packet::types::Algorithm::SHA256 => {
let mut mac = Hmac::<Sha256>::new(key.as_bytes());
mac.input(packet.get_payload().as_bytes());
let signature = packet.get_signature();
mac.verify(signature)
},
packet::types::Algorithm::SHA512 => {
let mut mac = Hmac::<Sha512>::new(key.as_bytes());
mac.input(packet.get_payload().as_bytes());
let signature = packet.get_signature();
mac.verify(signature)
},
};
return result;
}
答案 0 :(得分:1)
你的C实现与package_size
不一致,你在100字节硬编码。当您的防锈代码使用正确的消息时,您可以在C实现中有效地使用消息{"alg":"SHA256","id":1,"data":"DOGOOS","time":3,"expire":1}\x00\x00\x00\x00...\x00
。
在python中演示:
>>> import hashlib
>>> import hmac
>>> import base64
>>> correct_msg = b'{"alg":"SHA256","id":1,"data":"DOGOOS","time":3,"expire":1}'
>>> badly_padded_msg = correct_msg + b'\x00'*(100-len(msg))
>>> key = b'Secret and secure key!';
>>> base64.encodebytes(hmac.HMAC(key, correct_msg, hashlib.sha256).digest())
b'6DE3KUbbF6nKttaKIWRQaKAgdA7gG1JiPU63L1uPOww=\n'
>>> base64.encodebytes(hmac.HMAC(key, badly_padded_msg, hashlib.sha256).digest())
b'egL2gFU2DZVNkTk7jzhl7YJOKhHOWqTh/pUi3G2G2C4=\n'