0

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; } 
2
  • Please show your code, including your server code. Since Stack Overflow hides the Close reason from you: Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example. Commented Feb 15, 2018 at 1:43
  • So gave some more code Commented Feb 15, 2018 at 12:24

1 Answer 1

1

Your C implementation is incorrect with respect to package_size, which you hardcoded at 100 bytes. You effectively use the message {"alg":"SHA256","id":1,"data":"DOGOOS","time":3,"expire":1}\x00\x00\x00\x00...\x00 in your C-implementation while your rust-code uses the correct message.

Demonstrated in 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' 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.