fix jinzhi sign
This commit is contained in:
parent
e251ffbb79
commit
921a7f7964
@ -93,11 +93,16 @@ handle_call(_Request, _From, State = #state{}) ->
|
|||||||
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
{noreply, NewState :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term(), NewState :: #state{}}).
|
{stop, Reason :: term(), NewState :: #state{}}).
|
||||||
handle_cast({forward, LocationCode, DynamicLocationCode, EventType, Params}, State = #state{id = Id, timer_map = TimerMap, pri_key = PriKey, url = Url}) ->
|
handle_cast({forward, LocationCode, DynamicLocationCode, EventType, Params}, State = #state{id = Id, timer_map = TimerMap, pri_key = PriKey, url = Url}) ->
|
||||||
ReqBody = format_events(LocationCode, DynamicLocationCode, EventType, Params, PriKey),
|
try
|
||||||
catch do_post(Url, Id, ReqBody),
|
ReqBody = format_event(LocationCode, DynamicLocationCode, EventType, Params, PriKey),
|
||||||
TimerRef = erlang:start_timer(?RETRY_INTERVAL, self(), {repost_ticker, Id, ReqBody}),
|
catch do_post(Url, Id, ReqBody),
|
||||||
|
TimerRef = erlang:start_timer(?RETRY_INTERVAL, self(), {repost_ticker, Id, ReqBody}),
|
||||||
|
|
||||||
{noreply, State#state{id = Id + 1, timer_map = maps:put(Id, TimerRef, TimerMap)}}.
|
{noreply, State#state{id = Id + 1, timer_map = maps:put(Id, TimerRef, TimerMap)}}
|
||||||
|
catch _:Err:Stack ->
|
||||||
|
lager:warning("[iot_jinzhi_endpoint] format_event get error: ~p, stack: ~p", [Err, Stack]),
|
||||||
|
{noreply, State}
|
||||||
|
end.
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
%% @doc Handling all non call/cast messages
|
%% @doc Handling all non call/cast messages
|
||||||
@ -174,8 +179,8 @@ do_post(Url, Id, Body) when is_list(Url), is_integer(Id), is_binary(Body) ->
|
|||||||
end).
|
end).
|
||||||
|
|
||||||
%% 格式话要发送的数据,避免多次格式化处理
|
%% 格式话要发送的数据,避免多次格式化处理
|
||||||
-spec format_events(LocationCode :: binary(), DynamicLocationCode :: binary(), EventType :: integer(), Params :: map(), PriKey :: public_key:private_key()) -> binary().
|
-spec format_event(LocationCode :: binary(), DynamicLocationCode :: binary(), EventType :: integer(), Params :: map(), PriKey :: public_key:private_key()) -> binary().
|
||||||
format_events(LocationCode, DynamicLocationCode, EventType, #{<<"event_code">> := EventCode, <<"description">> := Description, <<"datetime">> := Datetime, <<"attachments">> := Attachments0}, PriKey)
|
format_event(LocationCode, DynamicLocationCode, EventType, #{<<"event_code">> := EventCode, <<"description">> := Description, <<"datetime">> := Datetime, <<"attachments">> := Attachments0}, PriKey)
|
||||||
when is_binary(LocationCode), is_binary(DynamicLocationCode), is_integer(EventType) ->
|
when is_binary(LocationCode), is_binary(DynamicLocationCode), is_integer(EventType) ->
|
||||||
|
|
||||||
Attachments = lists:map(fun(#{<<"filename">> := Filename}) ->
|
Attachments = lists:map(fun(#{<<"filename">> := Filename}) ->
|
||||||
@ -205,7 +210,7 @@ format_events(LocationCode, DynamicLocationCode, EventType, #{<<"event_code">> :
|
|||||||
},
|
},
|
||||||
|
|
||||||
ReqData = #{
|
ReqData = #{
|
||||||
<<"sign">> => iot_jinzhi_signer:sign(DeviceInfo, PriKey),
|
<<"sign">> => sign(DeviceInfo, PriKey),
|
||||||
<<"sysId">> => ?SYS_ID,
|
<<"sysId">> => ?SYS_ID,
|
||||||
<<"taskId">> => generate_task_id(DynamicLocationCode, EventCode),
|
<<"taskId">> => generate_task_id(DynamicLocationCode, EventCode),
|
||||||
<<"count">> => 1,
|
<<"count">> => 1,
|
||||||
@ -233,3 +238,42 @@ generate_private_key(PriFile) when is_list(PriFile) ->
|
|||||||
{ok, PriKeyData} = file:read_file(PriKeyFile),
|
{ok, PriKeyData} = file:read_file(PriKeyFile),
|
||||||
PriDerData = base64:decode(PriKeyData),
|
PriDerData = base64:decode(PriKeyData),
|
||||||
public_key:der_decode('PrivateKeyInfo', PriDerData).
|
public_key:der_decode('PrivateKeyInfo', PriDerData).
|
||||||
|
|
||||||
|
|
||||||
|
%% 数据签名
|
||||||
|
-spec sign(M :: #{}, PrivateKey :: public_key:private_key()) -> binary().
|
||||||
|
sign(M, PrivateKey) when is_map(M) ->
|
||||||
|
Json = serialize(M),
|
||||||
|
Hash = iolist_to_binary(io_lib:format("~64.16.0b", [binary:decode_unsigned(crypto:hash(sha256, Json))])),
|
||||||
|
RsaEncoded = public_key:encrypt_private(Hash, PrivateKey),
|
||||||
|
base64:encode(RsaEncoded).
|
||||||
|
|
||||||
|
%% 简单的序列号,sign签名
|
||||||
|
-spec serialize(M :: map()) -> JsonString :: binary().
|
||||||
|
serialize(M) when is_map(M) ->
|
||||||
|
L = maps:to_list(M),
|
||||||
|
L1 = lists:sort(fun({K, _}, {K1, _}) -> K < K1 end, L),
|
||||||
|
serialize0(L1, []).
|
||||||
|
|
||||||
|
serialize0([], Target) ->
|
||||||
|
B = iolist_to_binary(lists:join(<<$,>>, lists:reverse(Target))),
|
||||||
|
<<${, B/binary, $}>>;
|
||||||
|
serialize0([{K, V}|T], Target) ->
|
||||||
|
V1 = if
|
||||||
|
is_integer(V) ->
|
||||||
|
integer_to_binary(V);
|
||||||
|
is_float(V) ->
|
||||||
|
float_to_binary(V);
|
||||||
|
is_binary(V) ->
|
||||||
|
<<$", V/binary, $">>;
|
||||||
|
is_boolean(V) andalso V ->
|
||||||
|
<<"true">>;
|
||||||
|
is_boolean(V) andalso not V ->
|
||||||
|
<<"false">>;
|
||||||
|
is_list(V) ->
|
||||||
|
Items = lists:map(fun(E) -> serialize(E) end, V),
|
||||||
|
V0 = iolist_to_binary(lists:join(<<$,>>, Items)),
|
||||||
|
<<$[, V0/binary, $]>>
|
||||||
|
end,
|
||||||
|
Item = <<$", K/binary, $", $:, V1/binary>>,
|
||||||
|
serialize0(T, [Item|Target]).
|
||||||
@ -1,51 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author anlicheng
|
|
||||||
%%% @copyright (C) 2024, <COMPANY>
|
|
||||||
%%% @doc
|
|
||||||
%%% 中电的签名逻辑
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 02. 9月 2024 11:28
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(iot_jinzhi_signer).
|
|
||||||
-author("anlicheng").
|
|
||||||
|
|
||||||
%% API
|
|
||||||
-export([sign/2]).
|
|
||||||
|
|
||||||
%% 数据签名
|
|
||||||
-spec sign(M :: #{}, PrivateKey :: public_key:private_key()) -> binary().
|
|
||||||
sign(M, PrivateKey) when is_map(M) ->
|
|
||||||
Json = serialize(M),
|
|
||||||
Hash = iolist_to_binary(io_lib:format("~64.16.0b", [binary:decode_unsigned(crypto:hash(sha256, Json))])),
|
|
||||||
RsaEncoded = public_key:encrypt_private(Hash, PrivateKey),
|
|
||||||
|
|
||||||
base64:encode(RsaEncoded).
|
|
||||||
|
|
||||||
%% 简单的序列号,sign签名
|
|
||||||
-spec serialize(M :: map()) -> JsonString :: binary().
|
|
||||||
serialize(M) when is_map(M) ->
|
|
||||||
L = maps:to_list(M),
|
|
||||||
L1 = lists:sort(fun({K, _}, {K1, _}) -> K < K1 end, L),
|
|
||||||
serialize(L1, []).
|
|
||||||
serialize([], Target) ->
|
|
||||||
B = iolist_to_binary(lists:join(<<$,>>, lists:reverse(Target))),
|
|
||||||
<<${, B/binary, $}>>;
|
|
||||||
serialize([{K, V}|T], Target) ->
|
|
||||||
V1 = if
|
|
||||||
is_integer(V) ->
|
|
||||||
integer_to_binary(V);
|
|
||||||
is_float(V) ->
|
|
||||||
float_to_binary(V);
|
|
||||||
is_binary(V) ->
|
|
||||||
<<$", V/binary, $">>;
|
|
||||||
is_boolean(V) andalso V ->
|
|
||||||
<<"true">>;
|
|
||||||
is_boolean(V) andalso not V ->
|
|
||||||
<<"false">>;
|
|
||||||
is_list(V) ->
|
|
||||||
Items = lists:map(fun(E) -> serialize(E) end, V),
|
|
||||||
V0 = iolist_to_binary(lists:join(<<$,>>, Items)),
|
|
||||||
<<$[, V0/binary, $]>>
|
|
||||||
end,
|
|
||||||
Item = <<$", K/binary, $", $:, V1/binary>>,
|
|
||||||
serialize(T, [Item|Target]).
|
|
||||||
Loading…
x
Reference in New Issue
Block a user