Packages

NeteaseMusic API's Elixir version base Plug.

Current section

Files

Jump to
netease_music_api lib helpers crypto.ex
Raw

lib/helpers/crypto.ex

defmodule Helpers.Crypto do
@moduledoc false
# 常量
# 参考 https://github.com/darknessomi/musicbox/wiki/
@nonce "0CoJUm6Qyw8W8jud"
@modules "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7" |> Integer.parse(16) |> elem(0)
@pubkey "010001" |> Integer.parse(16) |> elem(0)
@keys "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" |> String.codepoints
@doc false
def create_secret_key(size) do
1..size
|> Enum.map(fn _ -> Enum.random(@keys) end)
|> Enum.join()
end
@doc false
@spec pad(String.t(), integer) :: String.t()
def pad(data, block_size) do
to_add = block_size - rem(byte_size(data), block_size)
data <> to_string(:string.chars(to_add, to_add))
end
@doc false
def aes_encrypt(text, seckey) do
lv = "0102030405060708"
:crypto.block_encrypt(:aes_cbc128, seckey, lv, pad(text, 16)) |> Base.encode64
end
@doc false
def ras_encrypt(text, pubkey, modules) do
text = text |> String.codepoints() |> Enum.reverse() |> Enum.join()
bitext = text |> Base.encode16 |> Integer.parse(16) |> elem(0)
:crypto.mod_pow(bitext, pubkey, modules) |> Base.encode16(case: :lower) |> String.pad_leading(256, "0")
end
@doc false
def encrypt(obj, seckey \\ create_secret_key(16)) do
{:ok, text} = Poison.encode(obj)
enc_text = text |> aes_encrypt(@nonce) |> aes_encrypt(seckey)
enc_seckey = ras_encrypt(seckey, @pubkey, @modules)
[{"params", enc_text}, {"encSecKey", enc_seckey}]
end
end