I am working on library that HMAC input to get a signature, the signature will then be checked on the server to validated the sender. My problem is that the library and server generates different HMAC. I use the HMAC function provided by the OpenSSL package.
The key is Secret and secure key! and the package (data) is {"alg":"SHA256","id":1,"data":"DOGOOS","time":3,"expire":1} and it generates the following signature egL2gFU2DZVNkTk7jzhl7YJOKhHOWqTh/pUi3G2G2C4= while my server generates 6DE3KUbbF6nKttaKIWRQaKAgdA7gG1JiPU63L1uPOww= for the same data.
I also tested to generate a signature from this website https://www.liavaag.org/English/SHA-Generator/HMAC/ with the following settings and it yields the same result as my server.
Input type: Text Key type: Text Sha variant: SHA256 Output type: Base64 I have verified that the Base64Encode function works properly.
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; } As requested this is the code on the server side. It is written in rust. I generates the same result as the websites I trired so for all tests I have done the server yields the correct output.
#[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; }