Openssl hmac产生不同的结果

时间:2018-02-14 09:19:11

标签: c openssl

我正在处理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;
} 

1 个答案:

答案 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'