Message Encryptor 和 Message Verifier

两部分: Message Verifier 和 Message Encryptor.

Message Verifier

生成加密的文本,然后用于校验。这里的加密仅意味着"加签名、防篡改",过程是可逆的,请注意使用场景。 使用场景举例,生成"记住我"的 token,或生成"取消订阅"的链接。

verifier = ActiveSupport::MessageVerifier.new('your-secret')
message = "String that is prevented from tampering."

# 签名(加密)
signed_message = verifier.generate(message)

# 验证(解密)
verified = verifier.verify(signed_message)

# 比较
verified == message
# => true

主要是 generate(value)verify(signed_message),原理很简单,这里不多赘述。

另,验证加密信息是否被篡改:

verifier = ActiveSupport::MessageVerifier.new 's3Krit'
signed_message = verifier.generate 'a private message'
verifier.valid_message?(signed_message) # => true

tampered_message = signed_message.chop # 篡改"已经签名"的信息
verifier.valid_message?(tampered_message) # => false

其它方法:

verified

valid_message?

Message Encryptor

和 Message Verifier 本质上没有区别。但使用上会更严格一点,会多一些步骤(相应地,也更安全了一点),并且它也有调用到 Message Verifier.

还有一个优点:Message Encryptor 生成的字符串会比较短,比 Message Verifier 生成的更适合直接放到 url 里。

使用举例:

salt = SecureRandom.random_bytes(64)
secret_key_base = '-- secret key base --'

key_generator = ActiveSupport::KeyGenerator.new(secret_key_base)
# 生成密钥
key = key_generator.generate_key(salt)

encryptor1 = ActiveSupport::MessageEncryptor.new(key)
encryptor2 = ActiveSupport::MessageEncryptor.new(key)

message = "Encrypted string."

# 加密
encrypted_message = encryptor1.encrypt_and_sign(message)

# 解密
decrypted = encryptor2.decrypt_and_verify(encrypted_message)

# 比较
decrypted == message
# => true

主要是 encrypt_and_sign(value)decrypt_and_verify(value),同样这里不多赘述。

Message Encryptor、Message Verifier 和 Key Generator 这三者使用类似,创建时可传递字符串做为参数,然后进行加密,生成的也是字符串。

实例参考

salt  = SecureRandom.random_bytes(64) # 保存进数据库
secret_key_base = '-- secret base --' # 保存到配置文件

string = 'string'                     # 运行于代码
secret = Digest::MD5.hexdigest("#{secret_key_base}-#{string}")
key    = ActiveSupport::KeyGenerator.new(secret).generate_key(salt)
crypt1 = ActiveSupport::MessageEncryptor.new(key)

string = 'string'                     # 运行于代码
secret = Digest::MD5.hexdigest("#{secret_key_base}-#{string}")
key    = ActiveSupport::KeyGenerator.new(secret).generate_key(salt)
crypt2 = ActiveSupport::MessageEncryptor.new(key)

source_data    = 'my secret data'                     # 加密前数据
encrypted_data = crypt1.encrypt_and_sign(source_data) # 加密后数据
decode_data    = crypt2.decrypt_and_verify(encrypted_data)
source_data == decode_data

Note: 注意和【Key Generator 和 Caching Key Generator】章节的联系。

最后更新于