类 OpenSSL::HMAC
OpenSSL::HMAC
允许计算基于哈希的消息认证码 (HMAC
)。它是一种消息认证码 (MAC),涉及将哈希函数与密钥结合使用。 HMAC
可用于验证消息的完整性和真实性。
OpenSSL::HMAC
与 OpenSSL::Digest
具有类似的接口。
使用一次性接口的 HMAC-SHA256¶ ↑
key = "key" data = "message-to-be-authenticated" mac = OpenSSL::HMAC.hexdigest("SHA256", key, data) #=> "cddb0db23f469c8bf072b21fd837149bd6ace9ab771cceef14c9e517cc93282e"
使用增量接口的 HMAC-SHA256¶ ↑
data1 = File.binread("file1") data2 = File.binread("file2") key = "key" hmac = OpenSSL::HMAC.new(key, 'SHA256') hmac << data1 hmac << data2 mac = hmac.digest
公共类方法
返回认证码作为 Base64 编码的字符串。digest 参数指定要使用的摘要算法。这可以是表示算法名称的字符串,也可以是 OpenSSL::Digest
的实例。
示例¶ ↑
key = 'key' data = 'The quick brown fox jumps over the lazy dog' hmac = OpenSSL::HMAC.base64digest('SHA1', key, data) #=> "3nybhbi3iqa8ino29wqQcBydtNk="
# File openssl/lib/openssl/hmac.rb, line 73 def base64digest(digest, key, data) [digest(digest, key, data)].pack("m0") end
返回认证码作为二进制字符串。digest 参数指定要使用的摘要算法。这可以是表示算法名称的字符串,也可以是 OpenSSL::Digest
的实例。
示例¶ ↑
key = 'key' data = 'The quick brown fox jumps over the lazy dog' hmac = OpenSSL::HMAC.digest('SHA1', key, data) #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
# File openssl/lib/openssl/hmac.rb, line 35 def digest(digest, key, data) hmac = new(key, digest) hmac << data hmac.digest end
返回认证码作为十六进制编码的字符串。digest 参数指定要使用的摘要算法。这可以是表示算法名称的字符串,也可以是 OpenSSL::Digest
的实例。
示例¶ ↑
key = 'key' data = 'The quick brown fox jumps over the lazy dog' hmac = OpenSSL::HMAC.hexdigest('SHA1', key, data) #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
# File openssl/lib/openssl/hmac.rb, line 54 def hexdigest(digest, key, data) hmac = new(key, digest) hmac << data hmac.hexdigest end
返回一个 OpenSSL::HMAC
实例,该实例设置了要使用的密钥和摘要算法。该实例表示在处理任何数据之前消息认证码的初始状态。要使用它处理数据,请使用实例方法 update
,并将您的数据作为参数传递。
示例¶ ↑
key = 'key' instance = OpenSSL::HMAC.new(key, 'SHA1') #=> f42bb0eeb018ebbd4597ae7213711ec60760843f instance.class #=> OpenSSL::HMAC
关于比较的说明¶ ↑
可以使用 ==
以恒定时间安全地比较两个实例。
other_instance = OpenSSL::HMAC.new('key', 'SHA1') #=> f42bb0eeb018ebbd4597ae7213711ec60760843f instance == other_instance #=> true
static VALUE ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) { EVP_MD_CTX *ctx; EVP_PKEY *pkey; GetHMAC(self, ctx); StringValue(key); #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, (unsigned char *)RSTRING_PTR(key), RSTRING_LENINT(key)); if (!pkey) ossl_raise(eHMACError, "EVP_PKEY_new_raw_private_key"); #else pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, (unsigned char *)RSTRING_PTR(key), RSTRING_LENINT(key)); if (!pkey) ossl_raise(eHMACError, "EVP_PKEY_new_mac_key"); #endif if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest), NULL, pkey) != 1) { EVP_PKEY_free(pkey); ossl_raise(eHMACError, "EVP_DigestSignInit"); } /* Decrement reference counter; EVP_MD_CTX still keeps it */ EVP_PKEY_free(pkey); return self; }
公共实例方法
返回使用要验证的消息更新的 hmac。可以多次调用它,并传递消息的各个部分。
示例¶ ↑
first_chunk = 'The quick brown fox jumps ' second_chunk = 'over the lazy dog' instance.update(first_chunk) #=> 5b9a8038a65d571076d97fe783989e52278a492a instance.update(second_chunk) #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
以恒定时间安全地与另一个 HMAC
实例进行比较。
# File openssl/lib/openssl/hmac.rb, line 6 def ==(other) return false unless HMAC === other return false unless self.digest.bytesize == other.digest.bytesize OpenSSL.fixed_length_secure_compare(self.digest, other.digest) end
返回以 Base64 编码的字符串形式表示的认证码。
# File openssl/lib/openssl/hmac.rb, line 17 def base64digest [digest].pack("m0") end
返回实例表示的认证码,以二进制字符串形式表示。
示例¶ ↑
instance = OpenSSL::HMAC.new('key', 'SHA1') #=> f42bb0eeb018ebbd4597ae7213711ec60760843f instance.digest #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
static VALUE ossl_hmac_digest(VALUE self) { EVP_MD_CTX *ctx; size_t buf_len = EVP_MAX_MD_SIZE; VALUE ret; GetHMAC(self, ctx); ret = rb_str_new(NULL, EVP_MAX_MD_SIZE); if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len) != 1) ossl_raise(eHMACError, "EVP_DigestSignFinal"); rb_str_set_len(ret, (long)buf_len); return ret; }
返回实例表示的认证码,以十六进制编码的字符串形式表示。
static VALUE ossl_hmac_hexdigest(VALUE self) { EVP_MD_CTX *ctx; unsigned char buf[EVP_MAX_MD_SIZE]; size_t buf_len = EVP_MAX_MD_SIZE; VALUE ret; GetHMAC(self, ctx); if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1) ossl_raise(eHMACError, "EVP_DigestSignFinal"); ret = rb_str_new(NULL, buf_len * 2); ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len); return ret; }
static VALUE ossl_hmac_copy(VALUE self, VALUE other) { EVP_MD_CTX *ctx1, *ctx2; rb_check_frozen(self); if (self == other) return self; GetHMAC(self, ctx1); GetHMAC(other, ctx2); if (EVP_MD_CTX_copy(ctx1, ctx2) != 1) ossl_raise(eHMACError, "EVP_MD_CTX_copy"); return self; }
返回认证码作为十六进制编码的字符串。digest 参数指定要使用的摘要算法。这可以是表示算法名称的字符串,也可以是 OpenSSL::Digest
的实例。
示例¶ ↑
key = 'key' data = 'The quick brown fox jumps over the lazy dog' hmac = OpenSSL::HMAC.hexdigest('SHA1', key, data) #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
返回hmac,它与首次初始化时相同,所有已处理的数据都已清除。
示例¶ ↑
data = "The quick brown fox jumps over the lazy dog" instance = OpenSSL::HMAC.new('key', 'SHA1') #=> f42bb0eeb018ebbd4597ae7213711ec60760843f instance.update(data) #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 instance.reset #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
static VALUE ossl_hmac_reset(VALUE self) { EVP_MD_CTX *ctx; EVP_PKEY *pkey; GetHMAC(self, ctx); pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx)); if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1) ossl_raise(eHMACError, "EVP_DigestSignInit"); return self; }
返回认证码作为十六进制编码的字符串。digest 参数指定要使用的摘要算法。这可以是表示算法名称的字符串,也可以是 OpenSSL::Digest
的实例。
示例¶ ↑
key = 'key' data = 'The quick brown fox jumps over the lazy dog' hmac = OpenSSL::HMAC.hexdigest('SHA1', key, data) #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
返回使用要验证的消息更新的 hmac。可以多次调用它,并传递消息的各个部分。
示例¶ ↑
first_chunk = 'The quick brown fox jumps ' second_chunk = 'over the lazy dog' instance.update(first_chunk) #=> 5b9a8038a65d571076d97fe783989e52278a492a instance.update(second_chunk) #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
static VALUE ossl_hmac_update(VALUE self, VALUE data) { EVP_MD_CTX *ctx; StringValue(data); GetHMAC(self, ctx); if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) ossl_raise(eHMACError, "EVP_DigestSignUpdate"); return self; }