⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srp.pas

📁 cipher 5.1。一个几乎包含了所有常见的加密算法的控件
💻 PAS
字号:
{Copyright:      Hagen Reddmann  HaReddmann at T-Online dot de
 Author:         Hagen Reddmann
 Remarks:        this Copyright must be included
 known Problems: none
 Version:        5.1,  Part II from Delphi Encryption Compendium
                 Delphi 5
 Description:    Counter-SRP, modified Secure Remote Password Protocoll
                 based on SRP-6a

                 All Interfaced are declared to support own DLL's to
                 other languages that supports COM Objects. Thus the use of
                 WideString.

                 Normaly the programmer provide a custom ISRPDatabase Interface
                 to he's own Database of Users. Such Database have only two
                 columns -> Identifier and Data of type String.

                 Here we provide two such ISRPDatabase Impelmentation:
                 - in textbased INI Files
                 - in Registry of current user

                 The ISRPDatabase Interface are most globaly used and must provide
                 a threadsafe way to access the records, eg. should use RTL-
                 Critical Sections.

                 The ISRPServer and ISRPClient are only allocated live in the
                 Connections Threads of our TCP/IP Library, as example iff we use
                 INDY componnents the we allocate these Interfaces in the threaded
                 TCP/IP Method of TidTCPServer and TidTCPClient.

                 This is because that a ISRPClient/ISRPSever Interface holds only
                 one current session of one attemp for secret sharing.

 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

}
{$I VER.INC}
unit SRP;

interface

type
  ISRPDatabase = interface
    ['{FCFBEF2F-1C57-401D-BACC-10CDC6252A78}']
    function Lookup(const Ident: WideString): WideString; stdcall;
    procedure Store(const Ident, Data: WideString); stdcall;
    procedure Delete(const Ident: WideString); stdcall;
  end;

  TSRPState = (srpNone, srpStep0, srpStep1, srpFinish);

  ISRPServer = interface
    ['{82A45C14-A133-4C26-AF61-DA1DD59AB3EE}']
    function State: TSRPState; stdcall;
    function SharedSecret: WideString; stdcall;
    function Counter: Cardinal; stdcall;
    function Identifier: WideString; stdcall;
    function Encrypt(const Msg: WideString): WideString; stdcall;
    function Decrypt(const Msg: WideString): WideString; stdcall;
    function Step0(const Msg: WideString): WideString; stdcall;
    function Step1(const Msg: WideString): WideString; stdcall;
    function RegisterClient(const Name: WideString): WideString; stdcall;
  end;

  ISRPClient = interface
    ['{A690EE81-A46A-4FC9-B55F-88EE3D665E6C}']
    function State: TSRPState; stdcall;
    function SharedSecret: WideString; stdcall;
    function Counter: Cardinal; stdcall;
    function Identifier: WideString; stdcall;
    function Encrypt(const Msg: WideString): WideString; stdcall;
    function Decrypt(const Msg: WideString): WideString; stdcall;
    function Step0(const Name: WideString; const OldPassword: WideString; const NewPassword: WideString = ''): WideString; stdcall;
    function Step1(const Msg: WideString): WideString; stdcall;
    function Step2(const Msg: WideString): WideString; stdcall;
  end;

// these functions should be exported if a DLL is used
function SRPDatabase(InRegistry: Boolean = False): ISRPDatabase; stdcall;
function SRPServer(const ADatabase: ISRPDatabase): ISRPServer; stdcall;
function SRPClient: ISRPClient; stdcall;

implementation
(*
Counter-SRP-6

SecureBits            = integer
MGF([data])           = hash based Mask Generation Function, creates SecureBits length result
                        from a set of input parameters
MGF([data], index)    = MGF with Index > 0
OTP(data, key, index) = hash based One Time Pad, use an indexed KDF
RND()                 = secure random generator, produce SecureBits result

Name                  = plaintext Name of Client
I                     = Identifier of Client
S,S'                  = random Password Salt, SecureBits long
Sp                    = public OTP encrypted Salt
V,V'                  = Password Verifier
Vp                    = public OTP encrypted Verifier
P,P'                  = client passwords, old and new
C                     = incremental Counter, 32 Bits long, used as Index in the MGF
N                     = large Safe Prime, so called Sophie Germain Prime
g                     = Generator, > 3
k                     = hased security value
ID                    = string thats represent N,G,K in safe manner
b,B                   = empheral server keys, secret and public
a,A                   = empheral client keys, secret and public
K                     = shared secret key
Kd                    = derivate of K
???                   = question


 CLIENT                                   SERVER

 I  = MGF([Name])

                          -----------> I
                                          lookup I,S,V,C,ID in Database
                                          N,g = IDPrime(ID)
                                          k   = MGF([N, g])
                                          b   = RND()
                                          B   = k*V+g^b
                          S,C,B,ID <---
 B   = 0 ??? abort else ok

 N,g = IDPrime(ID)
 k   = MGF([N, g])

 x   = MGF([S, I, P], C)
 V   = g^x

 a   = RND()
 A   = g^a
 u   = MGF([A, B], C)
 K   = (B-k*V)^(a+u*x)

 S'  = RND()
 x'  = MGF([S', I, P'], C +1)
 V'  = g^x'

 Vp  = OTP(V', K, C +1)
 Sp  = OTP(S', K, C +1)

 Mc  = MGF([A, B, S', V'])
                          ----> Mc,A,Sp,Vp
                                         A  = 0 ??? abort else ok
                                         u  = MGF([A, B], C)
                                         K  = (A*V^u)^b

                                         S' = OTP(Sp, K, C +1)
                                         V' = OTP(Vp, K, C +1)

                                         M' = MGF([A, B, S', V'])
                                         M' = Mc ??? ok else abort

                                         Mh = MGF([A, B, S', V', Mc])
                                         store
                                           I,S=S',V=V',C=C+1
                          Mh <---------
 M' = MGF([A, B, S', V', Mc])
 M' = Mh ??? ok else abort

 Kd = MGF([K])                            Kd = MGF([K])
                          <-Data encrypted->
*)

uses Windows, SysUtils, Registry, INIFiles, DECUtil, DECFmt, DECHash, DECCipher,
     DECRandom, NMath, NInts, IDPrimes;

const
  SRP_HashClass   : TDECHashClass = THash_SHA1;
  SRP_CipherClass : TDECCipherClass = TCipher_Blowfish;
  SRP_SecureBits  : Integer = 256;
  SRP_Separator   : String = ';';                          // don't use same separator as for ID-Primes !!
  SRP_Format      : TStrFormat = (
    Base: 64;
    Plus: '';
    Minus: '';
    Zero: '';
    Comma: ',';
    DigitsPerBlock: 0;
    BlockSep: #0;
    BlockPadding: #0;
    DigitsPerLine: 0;
    LineSep: #13#10;
    LinePadding: #0;
    DigitsChars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    FormatChars: ' /\-+;:#~"()[]?_<>!

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -