elixir 的加解密demo

        在libcluster项目里,有关于crypto的加解密的东西,包括

encrypt和decrypt, 向量IV,key,和填充等基础概念,和erlang的调用差无二意

直接上代码:

 1  defp encrypt(_state, plaintext, password) do
 2     iv = :crypto.strong_rand_bytes(16)
 3     key = :crypto.hash(:sha256, password)
 4     ciphertext = :crypto.crypto_one_time(:aes_256_cbc, key, iv, pkcs7_pad(plaintext), true)
 5 
 6     {:ok, iv, ciphertext}
 7   end
 8 
 9   defp decrypt(state, ciphertext, password, iv) do
10     key = :crypto.hash(:sha256, password)
11 
12     with {:unpadding, {:ok, padded}} <- {:unpadding, safe_decrypt(state, key, iv, ciphertext)},
13          {:decrypt, {:ok, _plaintext} = res} <- {:decrypt, pkcs7_unpad(padded)} do
14       res
15     else
16       {:unpadding, :error} -> {:error, :decrypt}
17       {:decrypt, :error} -> {:error, :unpadding}
18     end
19   end
20 
21   defp safe_decrypt(state, key, iv, ciphertext) do
22     try do
23       {:ok, :crypto.crypto_one_time(:aes_256_cbc, key, iv, ciphertext, false)}
24     catch
25       :error, {tag, {file, line}, desc} ->
26         warn(state.topology, "decryption failed: #{inspect(tag)} (#{file}:#{line}): #{desc}")
27         :error
28     end
29   end
30 
31   #
32   # Pads a message using the PKCS #7 cryptographic message syntax.
33   #
34   # from: https://github.com/izelnakri/aes256/blob/master/lib/aes256.ex
35   #
36   # See: https://tools.ietf.org/html/rfc2315
37   # See: `pkcs7_unpad/1`
38   defp pkcs7_pad(message) do
39     bytes_remaining = rem(byte_size(message), 16)
40     padding_size = 16 - bytes_remaining
41     message <> :binary.copy(<<padding_size>>, padding_size)
42   end
43 
44   #
45   # Unpads a message using the PKCS #7 cryptographic message syntax.
46   #
47   # from: https://github.com/izelnakri/aes256/blob/master/lib/aes256.ex
48   #
49   # See: https://tools.ietf.org/html/rfc2315
50   # See: `pkcs7_pad/1`
51   defp pkcs7_unpad(<<>>), do: :error
52 
53   defp pkcs7_unpad(message) do
54     padding_size = :binary.last(message)
55 
56     if padding_size <= 16 do
57       message_size = byte_size(message)
58 
59       if binary_part(message, message_size, -padding_size) ===
60            :binary.copy(<<padding_size>>, padding_size) do
61         {:ok, binary_part(message, 0, message_size - padding_size)}
62       else
63         :error
64       end
65     else
66       :error
67     end
68   end
View Code

 

posted @ 2022-09-16 14:06  孤独信徒  阅读(28)  评论(0编辑  收藏  举报