1

crypto モジュールを使用して Erlang に SRP6 を実装しようとしていますが、一致するセッション キーを取得できません。256 ビットの素数を使用しています。1024 ビットの素数を使用すると、それらは一致します。オプションの scrambler パラメータを crypto:compute_key で除外しましたが、違いはありません。

セッションキーが一致しない理由を理解してくれる人はいますか?

-module(srp).
-export([test/0]).


getUsername() -> <<"alice">>.

getPassword() -> <<"password123">>.

getSalt() -> <<"mystrongsalt">>.

getGenerator() -> <<7>>.

%% srp version 6
getVersion() -> '6'.

% randomly generated 32 byte number
getClientPrivate() ->
    <<16#C49F832EE8D67ECF9E7F2785EB0622D8B3FE2344C00F96E1AEF4103CA44D51F9:256>>.

% randomly generated 32 byte number
getServerPrivate() ->
    <<16#6C78CCEAAEC15E69068A87795B2A20ED7B45CFC5A254EBE2F17F144A4D99DB18:256>>.


%% 32 byte prime number
%% used in mangos: https://github.com/mangoszero/server/blob/master/src/realmd/AuthSocket.cpp#L190
%% used in arcemu: http://arcemu.org/wiki/Server_Logon_Challenge
getPrime() ->
    <<16#894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7:256>>.



%% v = g^x
getVerifier() ->
    Generator = getGenerator(),
    Prime = getPrime(),
    DerivedKey = getDerivedKey(),
    crypto:mod_pow(Generator, DerivedKey, Prime).


%% x = H(salt, H(username, :, password))
getDerivedKey() ->
    Username = getUsername(),
    Password = getPassword(),
    Salt = getSalt(),
    crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]).



%% client public key
getClientPublic() ->
    PrivateKey = getClientPrivate(),
    Generator = getGenerator(),
    Prime = getPrime(),
    Version = getVersion(),
        {Pub, PrivateKey} = crypto:generate_key(srp, {user, [Generator, Prime, Version]}, PrivateKey),
    Pub.

%% server public key
getServerPublic() ->
    PrivateKey = getServerPrivate(),
    Generator = getGenerator(),
    Prime = getPrime(),
    Version = getVersion(),
    Verifier = getVerifier(),
    {Pub, PrivateKey} = crypto:generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, PrivateKey),
    Pub.


%% client session key
computeClientKey() ->
    ServerPublic = getServerPublic(),
    ClientPrivate = getClientPrivate(),
    ClientPublic = getClientPublic(),
    Generator = getGenerator(),
    Prime = getPrime(),
    Version = getVersion(),
    DerivedKey = getDerivedKey(),
    crypto:compute_key(srp, ServerPublic, {ClientPublic, ClientPrivate}, {user, [DerivedKey, Prime, Generator, Version]}).

%% server session key
computeServerKey() ->
    ClientPublic = getClientPublic(),
    ServerPrivate = getServerPrivate(),
    ServerPublic = getServerPublic(),
    Prime = getPrime(),
    Version = getVersion(),
    Verifier = getVerifier(),
    crypto:compute_key(srp, ClientPublic, {ServerPublic, ServerPrivate}, {host, [Verifier, Prime, Version]}).



test() ->
    %% these session keys should match
    ClientKey = computeClientKey(),
    ServerKey = computeServerKey(),
    io:format("client skey: ~p~n", [ClientKey]),
    io:format("server skey: ~p~n", [ServerKey]),
    ClientKey == ServerKey.

要点はここにあります https://gist.github.com/jcclinton/4cdc9f616927677737a2

4

1 に答える 1