ssh_rsa.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 295 行
ERL
295 行
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%%%% Description: rsa public-key sign and verify-module(ssh_rsa).-export([verify/3, sign/2]).-export([alg_name/0]).-include("ssh.hrl").-include("PKCS-1.hrl").-define(MGF(Seed,Len), mgf1((Seed),(Len))).-define(HASH(X), crypto:sha((X))).-define(HLen, 20).%% start() ->%% crypto:start().%% sign_file(File) ->%% start(),%% {ok,Bin} = file:read_file(File),%% {ok,Key} = ssh_file:private_host_rsa_key(user),%% sign(Key, Bin).%% verify_file(File, Sig) ->%% start(),%% {ok,Bin} = file:read_file(File),%% {ok,Key} = ssh_file:public_host_rsa_key(user),%% verify(Key, Bin, Sig).sign(Private,Mb) -> rsassa_pkcs1_v1_5_sign(Private,Mb).verify(Public,Mb,Sb) -> rsassa_pkcs1_v1_5_verify(Public,Mb,Sb).%% Integer to octet stringi2osp(X, XLen) -> ssh_bits:i2bin(X, XLen).%% Octet string to Integeros2ip(X) -> ssh_bits:bin2i(X).%% decrypt1, M = message representative%% rsaep(#ssh_key { public={N,E}}, M) ->%% ?ssh_assert(M >= 0 andalso M =< N-1, out_of_range),%% ssh_math:ipow(M, E, N).%% encrypt1, C = cipher representative%% rsadp(#ssh_key { public={N,_}, private={_,D}}, C) ->%% ?ssh_assert(C >= 0 andalso C =< N-1, out_of_range),%% ssh_math:ipow(C, D, N).%% sign1, M = message representativersasp1(#ssh_key { public={N,_}, private={_,D}}, M) -> ?ssh_assert((M >= 0 andalso M =< N-1), out_of_range), ssh_math:ipow(M, D, N).%% verify1, S =signature representativersavp1(#ssh_key { public={N,E}}, S) -> ?ssh_assert(S >= 0 andalso S =< N-1, out_of_range), ssh_math:ipow(S, E, N).%% M messaage%% rsaes_oaep_encrypt(Public, M) ->%% rsaes_oaep_encrypt(Public, M, <<>>).%% rsaes_oaep_encrypt(Public=#ssh_key { public={N,_E}}, M, L) ->%% ?ssh_assert(size(L) =< 16#ffffffffffffffff, label_to_long),%% K = (ssh_bits:isize(N)+7) div 8,%% MLen = size(M),%% %% LLen = size(L),%% ?ssh_assert(MLen =< K - 2*?HLen - 2, message_to_long),%% LHash = ?HASH(L),%% PS = ssh_bits:fill_bits(K - MLen - 2*?HLen - 2, 0),%% DB = <<LHash/binary, PS/binary, 16#01, M/binary>>,%% Seed = ssh_bits:random(?HLen),%% DbMask = ?MGF(Seed, K - ?HLen - 1),%% MaskedDB = ssh_bits:xor_bits(DB, DbMask),%% SeedMask = ?MGF(MaskedDB, ?HLen),%% MaskedSeed = ssh_bits:xor_bits(Seed, SeedMask),%% EM = <<16#00, MaskedSeed/binary, MaskedDB/binary>>,%% Mc = os2ip(EM),%% C = rsaep(Public, Mc),%% i2osp(C, K).%% rsaes_oaep_decrypt(Key, C) ->%% rsaes_oaep_decrypt(Key, C, <<>>).%% rsaes_oaep_decrypt(Private=#ssh_key { public={N,_},private={_,_}},Cb,L) ->%% ?ssh_assert(size(L) =< 16#ffffffffffffffff, label_to_long),%% K = (ssh_bits:isize(N)+7) div 8,%% ?ssh_assert(K == 2*?HLen + 2, decryption_error),%% C = os2ip(Cb),%% M = rsadp(Private, C),%% EM = i2osp(M, K),%% LHash = ?HASH(L),%% MLen = K - ?HLen -1,%% case EM of%% <<16#00, MaskedSeed:?HLen/binary, MaskedDB:MLen>> ->%% SeedMask = ?MGF(MaskedDB, ?HLen),%% Seed = ssh_bits:xor_bits(MaskedSeed, SeedMask),%% DbMask = ?MGF(Seed, K - ?HLen - 1),%% DB = ssh_bits:xor_bits(MaskedDB, DbMask),%% PSLen = K - MLen - 2*?HLen - 2,%% case DB of%% <<LHash:?HLen, _PS:PSLen/binary, 16#01, M/binary>> ->%% M;%% _ ->%% exit(decryption_error)%% end;%% _ ->%% exit(decryption_error)%% end.%% rsaes_pkcs1_v1_5_encrypt(Public=#ssh_key { public={N,_}}, M) -> %% K = (ssh_bits:isize(N)+7) div 8,%% MLen = size(M),%% ?ssh_assert(MLen =< K - 11, message_to_long),%% PS = ssh_bits:random(K - MLen - 3),%% EM = <<16#00,16#02,PS/binary,16#00,M/binary>>,%% Mc = os2ip(EM),%% C = rsaep(Public, Mc),%% i2osp(C, K).%% rsaes_pkcs1_v1_5_decrypt(Private=#ssh_key { public={N,_},private={_,_}},%% Cb) ->%% K = (ssh_bits:isize(N)+7) div 8,%% CLen = size(Cb),%% ?ssh_assert(CLen == K andalso K >= 11, decryption_error),%% C = os2ip(Cb),%% M = rsadp(Private, C),%% EM = i2osp(M, K),%% PSLen = K - CLen - 3,%% case EM of%% <<16#00, 16#02, _PS:PSLen/binary, 16#00, M>> ->%% M;%% _ ->%% exit(decryption_error)%% end.%% rsassa_pss_sign(Private=#ssh_key { public={N,_},private={_,_}},Mb) ->%% ModBits = ssh_bits:isize(N),%% K = (ModBits+7) div 8,%% EM = emsa_pss_encode(Mb, ModBits - 1),%% M = os2ip(EM),%% S = rsasp1(Private, M),%% i2osp(S, K).%% rsassa_pss_verify(Public=#ssh_key { public={N,_E}},Mb,Sb) ->%% ModBits = ssh_bits:isize(N),%% K = (ModBits+7) div 8,%% ?ssh_assert(size(Sb) == K, invalid_signature),%% S = os2ip(Sb),%% M = rsavp1(Public,S),%% EMLen = (ModBits-1+7) div 8,%% EM = i2osp(M, EMLen),%% emsa_pss_verify(Mb, EM, ModBits-1).rsassa_pkcs1_v1_5_sign(Private=#ssh_key { public={N,_},private={_,_D}},Mb) -> K = (ssh_bits:isize(N)+7) div 8, EM = emsa_pkcs1_v1_5_encode(Mb, K), M = os2ip(EM), S = rsasp1(Private, M), i2osp(S, K).rsassa_pkcs1_v1_5_verify(Public=#ssh_key { public={N,_E}}, Mb, Sb) -> K = (ssh_bits:isize(N)+7) div 8, ?ssh_assert(size(Sb) == K, invalid_signature), S = os2ip(Sb), M = rsavp1(Public, S), EM = i2osp(M, K), ?dbg(true, "verify K=~p S=~w\nM=~w\nEM=~w\n", [K, S, M, EM]), case emsa_pkcs1_v1_5_encode(Mb, K) of EM -> ok; _S -> {error, invalid_signature} % exit(invalid_signature) end.emsa_pkcs1_v1_5_encode(M, EMLen) -> H = ?HASH(M), %% Must use speical xxNull types here! Alg = #'AlgorithmNull' { algorithm = ?'id-sha1', parameters = <<>> }, {ok,TCode} = 'PKCS-1':encode('DigestInfoNull', #'DigestInfoNull'{ digestAlgorithm = Alg, digest = H }), T = list_to_binary(TCode), TLen = size(T), ?ssh_assert(EMLen >= TLen + 11, message_to_short), PS = ssh_bits:fill_bits(EMLen - TLen - 3, 16#ff), <<16#00, 16#01, PS/binary, 16#00, T/binary>>.%% emsa_pss_encode(M, EMBits) ->%% emsa_pss_encode(M, EMBits, 0).%% emsa_pss_encode(M, EMBits, SLen) ->%% ?ssh_assert(size(M) =< 16#ffffffffffffffff, message_to_long),%% EMLen = (EMBits + 7) div 8,%% MHash = ?HASH(M),%% ?ssh_assert(EMLen >= ?HLen + SLen + 2, encoding_error),%% Salt = ssh_bits:random(SLen),%% M1 = [16#00,16#00,16#00,16#00,16#00,16#00,16#00,16#00,%% MHash, Salt],%% H = ?HASH(M1),%% PS = ssh_bits:fill_bits(EMLen-SLen-?HLen-2, 0),%% DB = <<PS/binary, 16#01, Salt/binary>>,%% DbMask = ?MGF(H, EMLen - ?HLen -1),%% MaskedDB = ssh_bits:xor_bits(DB, DbMask),%% ZLen = 8*EMLen - EMBits,%% NZLen = (8 - (ZLen rem 8)) rem 8,%% <<_:ZLen, NZ:NZLen, MaskedDB1/binary>> = MaskedDB,%% MaskedDB2 = <<0:ZLen, NZ:NZLen, MaskedDB1/binary>>,%% <<MaskedDB2/binary, H/binary, 16#BC>>.%% emsa_pss_verify(M, EM, EMBits) ->%% emsa_pss_verify(M, EM, EMBits, 0).%% emsa_pss_verify(M, EM, EMBits, SLen) ->%% ?ssh_assert(size(M) =< 16#ffffffffffffffff, message_to_long),%% EMLen = (EMBits + 7) div 8,%% MHash = ?HASH(M),%% ?ssh_assert(EMLen >= ?HLen + SLen + 2, inconsistent),%% MaskLen = (EMLen - ?HLen - 1)-1,%% ZLen = 8*EMLen - EMBits,%% NZLen = (8 - (ZLen rem 8)) rem 8,%% case EM of%% <<0:ZLen,Nz:NZLen,MaskedDB1:MaskLen/binary, H:?HLen/binary, 16#BC>> ->%% MaskedDB = <<0:ZLen,Nz:NZLen,MaskedDB1/binary>>,%% DbMask = ?MGF(H, EMLen - ?HLen - 1),%% DB = ssh_bits:xor_bits(MaskedDB, DbMask),%% PSLen1 = (EMLen - SLen - ?HLen - 2) - 1,%% PS = ssh_bits:fill_bits(PSLen1, 0),%% case DB of%% <<_:ZLen,0:NZLen,PS:PSLen1/binary,16#01,Salt:SLen/binary>> ->%% M1 = [16#00,16#00,16#00,16#00,16#00,16#00,16#00,16#00,%% MHash, Salt],%% case ?HASH(M1) of%% H -> ok;%% _ -> exit(inconsistent)%% end;%% _ ->%% exit(inconsistent)%% end;%% _ ->%% exit(inconsistent)%% end. %% Mask generating function MGF1%% mgf1(MGFSeed, MaskLen) ->%% T = mgf1_loop(0, ((MaskLen + ?HLen -1) div ?HLen) - 1, MGFSeed, ""),%% <<R:MaskLen/binary, _/binary>> = T,%% R.%% mgf1_loop(Counter, N, _, T) when Counter > N ->%% list_to_binary(T);%% mgf1_loop(Counter, N, MGFSeed, T) ->%% C = i2osp(Counter, 4),%% mgf1_loop(Counter+1, N, MGFSeed, [T, ?HASH([MGFSeed, C])]).alg_name() -> "ssh-rsa".
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?