This commit is contained in:
2026-06-15 18:18:16 +08:00
parent 97c9fba14e
commit 2b9f134e5f
4164 changed files with 386922 additions and 79 deletions

View File

@@ -0,0 +1,168 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp
{
/**
* Implements the client side SRP-6a protocol. Note that this class is stateful, and therefore NOT threadsafe.
* This implementation of SRP is based on the optimized message sequence put forth by Thomas Wu in the paper
* "SRP-6: Improvements and Refinements to the Secure Remote Password Protocol, 2002"
*/
public class Srp6Client
{
protected BigInteger N;
protected BigInteger g;
protected BigInteger privA;
protected BigInteger pubA;
protected BigInteger B;
protected BigInteger x;
protected BigInteger u;
protected BigInteger S;
protected BigInteger M1;
protected BigInteger M2;
protected BigInteger Key;
protected IDigest digest;
protected SecureRandom random;
public Srp6Client()
{
}
/**
* Initialises the client to begin new authentication attempt
* @param N The safe prime associated with the client's verifier
* @param g The group parameter associated with the client's verifier
* @param digest The digest algorithm associated with the client's verifier
* @param random For key generation
*/
public virtual void Init(BigInteger N, BigInteger g, IDigest digest, SecureRandom random)
{
this.N = N;
this.g = g;
this.digest = digest;
this.random = random;
}
public virtual void Init(Srp6GroupParameters group, IDigest digest, SecureRandom random)
{
Init(group.N, group.G, digest, random);
}
/**
* Generates client's credentials given the client's salt, identity and password
* @param salt The salt used in the client's verifier.
* @param identity The user's identity (eg. username)
* @param password The user's password
* @return Client's public value to send to server
*/
public virtual BigInteger GenerateClientCredentials(byte[] salt, byte[] identity, byte[] password)
{
this.x = Srp6Utilities.CalculateX(digest, N, salt, identity, password);
this.privA = SelectPrivateValue();
this.pubA = g.ModPow(privA, N);
return pubA;
}
/**
* Generates client's verification message given the server's credentials
* @param serverB The server's credentials
* @return Client's verification message for the server
* @throws CryptoException If server's credentials are invalid
*/
public virtual BigInteger CalculateSecret(BigInteger serverB)
{
this.B = Srp6Utilities.ValidatePublicValue(N, serverB);
this.u = Srp6Utilities.CalculateU(digest, N, pubA, B);
this.S = CalculateS();
return S;
}
protected virtual BigInteger SelectPrivateValue()
{
return Srp6Utilities.GeneratePrivateValue(digest, N, g, random);
}
private BigInteger CalculateS()
{
BigInteger k = Srp6Utilities.CalculateK(digest, N, g);
BigInteger exp = u.Multiply(x).Add(privA);
BigInteger tmp = g.ModPow(x, N).Multiply(k).Mod(N);
return B.Subtract(tmp).Mod(N).ModPow(exp, N);
}
/**
* Computes the client evidence message M1 using the previously received values.
* To be called after calculating the secret S.
* @return M1: the client side generated evidence message
* @throws CryptoException
*/
public virtual BigInteger CalculateClientEvidenceMessage()
{
// Verify pre-requirements
if (this.pubA == null || this.B == null || this.S == null)
{
throw new CryptoException("Impossible to compute M1: " +
"some data are missing from the previous operations (A,B,S)");
}
// compute the client evidence message 'M1'
this.M1 = Srp6Utilities.CalculateM1(digest, N, pubA, B, S);
return M1;
}
/** Authenticates the server evidence message M2 received and saves it only if correct.
* @param M2: the server side generated evidence message
* @return A boolean indicating if the server message M2 was the expected one.
* @throws CryptoException
*/
public virtual bool VerifyServerEvidenceMessage(BigInteger serverM2)
{
// Verify pre-requirements
if (this.pubA == null || this.M1 == null || this.S == null)
{
throw new CryptoException("Impossible to compute and verify M2: " +
"some data are missing from the previous operations (A,M1,S)");
}
// Compute the own server evidence message 'M2'
BigInteger computedM2 = Srp6Utilities.CalculateM2(digest, N, pubA, M1, S);
if (computedM2.Equals(serverM2))
{
this.M2 = serverM2;
return true;
}
return false;
}
/**
* Computes the final session key as a result of the SRP successful mutual authentication
* To be called after verifying the server evidence message M2.
* @return Key: the mutually authenticated symmetric session key
* @throws CryptoException
*/
public virtual BigInteger CalculateSessionKey()
{
// Verify pre-requirements (here we enforce a previous calculation of M1 and M2)
if (this.S == null || this.M1 == null || this.M2 == null)
{
throw new CryptoException("Impossible to compute Key: " +
"some data are missing from the previous operations (S,M1,M2)");
}
this.Key = Srp6Utilities.CalculateKey(digest, N, S);
return Key;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4d9d608b0adeb74584b09b8baa01c07
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,167 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp
{
/**
* Implements the server side SRP-6a protocol. Note that this class is stateful, and therefore NOT threadsafe.
* This implementation of SRP is based on the optimized message sequence put forth by Thomas Wu in the paper
* "SRP-6: Improvements and Refinements to the Secure Remote Password Protocol, 2002"
*/
public class Srp6Server
{
protected BigInteger N;
protected BigInteger g;
protected BigInteger v;
protected SecureRandom random;
protected IDigest digest;
protected BigInteger A;
protected BigInteger privB;
protected BigInteger pubB;
protected BigInteger u;
protected BigInteger S;
protected BigInteger M1;
protected BigInteger M2;
protected BigInteger Key;
public Srp6Server()
{
}
/**
* Initialises the server to accept a new client authentication attempt
* @param N The safe prime associated with the client's verifier
* @param g The group parameter associated with the client's verifier
* @param v The client's verifier
* @param digest The digest algorithm associated with the client's verifier
* @param random For key generation
*/
public virtual void Init(BigInteger N, BigInteger g, BigInteger v, IDigest digest, SecureRandom random)
{
this.N = N;
this.g = g;
this.v = v;
this.random = random;
this.digest = digest;
}
public virtual void Init(Srp6GroupParameters group, BigInteger v, IDigest digest, SecureRandom random)
{
Init(group.N, group.G, v, digest, random);
}
/**
* Generates the server's credentials that are to be sent to the client.
* @return The server's public value to the client
*/
public virtual BigInteger GenerateServerCredentials()
{
BigInteger k = Srp6Utilities.CalculateK(digest, N, g);
this.privB = SelectPrivateValue();
this.pubB = k.Multiply(v).Mod(N).Add(g.ModPow(privB, N)).Mod(N);
return pubB;
}
/**
* Processes the client's credentials. If valid the shared secret is generated and returned.
* @param clientA The client's credentials
* @return A shared secret BigInteger
* @throws CryptoException If client's credentials are invalid
*/
public virtual BigInteger CalculateSecret(BigInteger clientA)
{
this.A = Srp6Utilities.ValidatePublicValue(N, clientA);
this.u = Srp6Utilities.CalculateU(digest, N, A, pubB);
this.S = CalculateS();
return S;
}
protected virtual BigInteger SelectPrivateValue()
{
return Srp6Utilities.GeneratePrivateValue(digest, N, g, random);
}
private BigInteger CalculateS()
{
return v.ModPow(u, N).Multiply(A).Mod(N).ModPow(privB, N);
}
/**
* Authenticates the received client evidence message M1 and saves it only if correct.
* To be called after calculating the secret S.
* @param M1: the client side generated evidence message
* @return A boolean indicating if the client message M1 was the expected one.
* @throws CryptoException
*/
public virtual bool VerifyClientEvidenceMessage(BigInteger clientM1)
{
// Verify pre-requirements
if (this.A == null || this.pubB == null || this.S == null)
{
throw new CryptoException("Impossible to compute and verify M1: " +
"some data are missing from the previous operations (A,B,S)");
}
// Compute the own client evidence message 'M1'
BigInteger computedM1 = Srp6Utilities.CalculateM1(digest, N, A, pubB, S);
if (computedM1.Equals(clientM1))
{
this.M1 = clientM1;
return true;
}
return false;
}
/**
* Computes the server evidence message M2 using the previously verified values.
* To be called after successfully verifying the client evidence message M1.
* @return M2: the server side generated evidence message
* @throws CryptoException
*/
public virtual BigInteger CalculateServerEvidenceMessage()
{
// Verify pre-requirements
if (this.A == null || this.M1 == null || this.S == null)
{
throw new CryptoException("Impossible to compute M2: " +
"some data are missing from the previous operations (A,M1,S)");
}
// Compute the server evidence message 'M2'
this.M2 = Srp6Utilities.CalculateM2(digest, N, A, M1, S);
return M2;
}
/**
* Computes the final session key as a result of the SRP successful mutual authentication
* To be called after calculating the server evidence message M2.
* @return Key: the mutual authenticated symmetric session key
* @throws CryptoException
*/
public virtual BigInteger CalculateSessionKey()
{
// Verify pre-requirements
if (this.S == null || this.M1 == null || this.M2 == null)
{
throw new CryptoException("Impossible to compute Key: " +
"some data are missing from the previous operations (S,M1,M2)");
}
this.Key = Srp6Utilities.CalculateKey(digest, N, S);
return Key;
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d0e886e67aac4f644ad184673e7b20e9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,163 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp
{
public class Srp6StandardGroups
{
private static BigInteger FromHex(string hex)
{
return new BigInteger(1, Hex.DecodeStrict(hex));
}
private static Srp6GroupParameters FromNG(string hexN, string hexG)
{
return new Srp6GroupParameters(FromHex(hexN), FromHex(hexG));
}
/*
* RFC 5054
*/
private const string rfc5054_1024_N = "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
+ "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
+ "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
+ "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A" + "FD5138FE8376435B9FC61D2FC0EB06E3";
private const string rfc5054_1024_g = "02";
public static readonly Srp6GroupParameters rfc5054_1024 = FromNG(rfc5054_1024_N, rfc5054_1024_g);
private const string rfc5054_1536_N = "9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA961"
+ "4B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F843"
+ "80B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0B"
+ "E3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF5"
+ "6EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734A"
+ "F7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E"
+ "8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB";
private const string rfc5054_1536_g = "02";
public static readonly Srp6GroupParameters rfc5054_1536 = FromNG(rfc5054_1536_N, rfc5054_1536_g);
private const string rfc5054_2048_N = "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC319294"
+ "3DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310D"
+ "CD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FB"
+ "D5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF74"
+ "7359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A"
+ "436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D"
+ "5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E73"
+ "03CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB6"
+ "94B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F" + "9E4AFF73";
private const string rfc5054_2048_g = "02";
public static readonly Srp6GroupParameters rfc5054_2048 = FromNG(rfc5054_2048_N, rfc5054_2048_g);
private const string rfc5054_3072_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
+ "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
+ "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
+ "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
+ "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
+ "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
+ "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
+ "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
+ "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
+ "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
+ "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC" + "E0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
private const string rfc5054_3072_g = "05";
public static readonly Srp6GroupParameters rfc5054_3072 = FromNG(rfc5054_3072_N, rfc5054_3072_g);
private const string rfc5054_4096_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
+ "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
+ "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
+ "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
+ "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
+ "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
+ "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
+ "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
+ "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
+ "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
+ "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC"
+ "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26"
+ "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB"
+ "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2"
+ "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127"
+ "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" + "FFFFFFFFFFFFFFFF";
private const string rfc5054_4096_g = "05";
public static readonly Srp6GroupParameters rfc5054_4096 = FromNG(rfc5054_4096_N, rfc5054_4096_g);
private const string rfc5054_6144_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
+ "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
+ "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
+ "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
+ "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
+ "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
+ "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
+ "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
+ "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
+ "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
+ "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC"
+ "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26"
+ "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB"
+ "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2"
+ "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127"
+ "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
+ "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406"
+ "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918"
+ "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151"
+ "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03"
+ "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F"
+ "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
+ "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B"
+ "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632"
+ "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E" + "6DCC4024FFFFFFFFFFFFFFFF";
private const string rfc5054_6144_g = "05";
public static readonly Srp6GroupParameters rfc5054_6144 = FromNG(rfc5054_6144_N, rfc5054_6144_g);
private const string rfc5054_8192_N = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
+ "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
+ "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
+ "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
+ "49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8"
+ "FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D"
+ "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C"
+ "180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"
+ "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D"
+ "04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D"
+ "B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226"
+ "1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
+ "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC"
+ "E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26"
+ "99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB"
+ "04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2"
+ "233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127"
+ "D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
+ "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406"
+ "AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918"
+ "DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151"
+ "2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03"
+ "F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F"
+ "BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
+ "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B"
+ "B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632"
+ "387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E"
+ "6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA"
+ "3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C"
+ "5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
+ "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC886"
+ "2F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6"
+ "6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC5"
+ "0846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268"
+ "359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6"
+ "FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF";
private const string rfc5054_8192_g = "13";
public static readonly Srp6GroupParameters rfc5054_8192 = FromNG(rfc5054_8192_N, rfc5054_8192_g);
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 639f4eb11063b374b9f415ea311f1c26
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,222 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp
{
public class Srp6Utilities
{
public static BigInteger CalculateK(IDigest digest, BigInteger N, BigInteger g)
{
return HashPaddedPair(digest, N, N, g);
}
public static BigInteger CalculateU(IDigest digest, BigInteger N, BigInteger A, BigInteger B)
{
return HashPaddedPair(digest, N, A, B);
}
public static BigInteger CalculateX(IDigest digest, BigInteger N, byte[] salt, byte[] identity, byte[] password)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return CalculateX(digest, N, salt.AsSpan(), identity.AsSpan(), password.AsSpan());
#else
byte[] output = new byte[digest.GetDigestSize()];
digest.BlockUpdate(identity, 0, identity.Length);
digest.Update((byte)':');
digest.BlockUpdate(password, 0, password.Length);
digest.DoFinal(output, 0);
digest.BlockUpdate(salt, 0, salt.Length);
digest.BlockUpdate(output, 0, output.Length);
digest.DoFinal(output, 0);
return new BigInteger(1, output);
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public static BigInteger CalculateX(IDigest digest, BigInteger N, ReadOnlySpan<byte> salt,
ReadOnlySpan<byte> identity, ReadOnlySpan<byte> password)
{
int digestSize = digest.GetDigestSize();
Span<byte> output = digestSize <= 128
? stackalloc byte[digestSize]
: new byte[digestSize];
digest.BlockUpdate(identity);
digest.Update((byte)':');
digest.BlockUpdate(password);
digest.DoFinal(output);
digest.BlockUpdate(salt);
digest.BlockUpdate(output);
digest.DoFinal(output);
return new BigInteger(1, output);
}
#endif
public static BigInteger GeneratePrivateValue(IDigest digest, BigInteger N, BigInteger g, SecureRandom random)
{
int minBits = System.Math.Min(256, N.BitLength / 2);
BigInteger min = BigInteger.One.ShiftLeft(minBits - 1);
BigInteger max = N.Subtract(BigInteger.One);
return BigIntegers.CreateRandomInRange(min, max, random);
}
public static BigInteger ValidatePublicValue(BigInteger N, BigInteger val)
{
val = val.Mod(N);
// Check that val % N != 0
if (val.Equals(BigInteger.Zero))
throw new CryptoException("Invalid public value: 0");
return val;
}
/**
* Computes the client evidence message (M1) according to the standard routine:
* M1 = H( A | B | S )
* @param digest The Digest used as the hashing function H
* @param N Modulus used to get the pad length
* @param A The public client value
* @param B The public server value
* @param S The secret calculated by both sides
* @return M1 The calculated client evidence message
*/
public static BigInteger CalculateM1(IDigest digest, BigInteger N, BigInteger A, BigInteger B, BigInteger S)
{
BigInteger M1 = HashPaddedTriplet(digest, N, A, B, S);
return M1;
}
/**
* Computes the server evidence message (M2) according to the standard routine:
* M2 = H( A | M1 | S )
* @param digest The Digest used as the hashing function H
* @param N Modulus used to get the pad length
* @param A The public client value
* @param M1 The client evidence message
* @param S The secret calculated by both sides
* @return M2 The calculated server evidence message
*/
public static BigInteger CalculateM2(IDigest digest, BigInteger N, BigInteger A, BigInteger M1, BigInteger S)
{
BigInteger M2 = HashPaddedTriplet(digest, N, A, M1, S);
return M2;
}
/**
* Computes the final Key according to the standard routine: Key = H(S)
* @param digest The Digest used as the hashing function H
* @param N Modulus used to get the pad length
* @param S The secret calculated by both sides
* @return
*/
public static BigInteger CalculateKey(IDigest digest, BigInteger N, BigInteger S)
{
int paddedLength = (N.BitLength + 7) / 8;
int digestSize = digest.GetDigestSize();
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Span<byte> bytes = paddedLength <= 512
? stackalloc byte[paddedLength]
: new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(S, bytes);
digest.BlockUpdate(bytes);
Span<byte> output = digestSize <= 128
? stackalloc byte[digestSize]
: new byte[digestSize];
digest.DoFinal(output);
#else
byte[] bytes = new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(S, bytes, 0, bytes.Length);
digest.BlockUpdate(bytes, 0, bytes.Length);
byte[] output = new byte[digestSize];
digest.DoFinal(output, 0);
#endif
return new BigInteger(1, output);
}
private static BigInteger HashPaddedTriplet(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2, BigInteger n3)
{
int paddedLength = (N.BitLength + 7) / 8;
int digestSize = digest.GetDigestSize();
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Span<byte> bytes = paddedLength <= 512
? stackalloc byte[paddedLength]
: new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(n1, bytes);
digest.BlockUpdate(bytes);
BigIntegers.AsUnsignedByteArray(n2, bytes);
digest.BlockUpdate(bytes);
BigIntegers.AsUnsignedByteArray(n3, bytes);
digest.BlockUpdate(bytes);
Span<byte> output = digestSize <= 128
? stackalloc byte[digestSize]
: new byte[digestSize];
digest.DoFinal(output);
#else
byte[] bytes = new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(n1, bytes, 0, bytes.Length);
digest.BlockUpdate(bytes, 0, bytes.Length);
BigIntegers.AsUnsignedByteArray(n2, bytes, 0, bytes.Length);
digest.BlockUpdate(bytes, 0, bytes.Length);
BigIntegers.AsUnsignedByteArray(n3, bytes, 0, bytes.Length);
digest.BlockUpdate(bytes, 0, bytes.Length);
byte[] output = new byte[digestSize];
digest.DoFinal(output, 0);
#endif
return new BigInteger(1, output);
}
private static BigInteger HashPaddedPair(IDigest digest, BigInteger N, BigInteger n1, BigInteger n2)
{
int paddedLength = (N.BitLength + 7) / 8;
int digestSize = digest.GetDigestSize();
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Span<byte> bytes = paddedLength <= 512
? stackalloc byte[paddedLength]
: new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(n1, bytes);
digest.BlockUpdate(bytes);
BigIntegers.AsUnsignedByteArray(n2, bytes);
digest.BlockUpdate(bytes);
Span<byte> output = digestSize <= 128
? stackalloc byte[digestSize]
: new byte[digestSize];
digest.DoFinal(output);
#else
byte[] bytes = new byte[paddedLength];
BigIntegers.AsUnsignedByteArray(n1, bytes, 0, bytes.Length);
digest.BlockUpdate(bytes, 0, bytes.Length);
BigIntegers.AsUnsignedByteArray(n2, bytes, 0, bytes.Length);
digest.BlockUpdate(bytes, 0, bytes.Length);
byte[] output = new byte[digestSize];
digest.DoFinal(output, 0);
#endif
return new BigInteger(1, output);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bd559eae0c629b947b49355114a17f2a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,59 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement.Srp
{
/**
* Generates new SRP verifier for user
*/
public class Srp6VerifierGenerator
{
protected BigInteger N;
protected BigInteger g;
protected IDigest digest;
public Srp6VerifierGenerator()
{
}
/**
* Initialises generator to create new verifiers
* @param N The safe prime to use (see DHParametersGenerator)
* @param g The group parameter to use (see DHParametersGenerator)
* @param digest The digest to use. The same digest type will need to be used later for the actual authentication
* attempt. Also note that the final session key size is dependent on the chosen digest.
*/
public virtual void Init(BigInteger N, BigInteger g, IDigest digest)
{
this.N = N;
this.g = g;
this.digest = digest;
}
public virtual void Init(Srp6GroupParameters group, IDigest digest)
{
Init(group.N, group.G, digest);
}
/**
* Creates a new SRP verifier
* @param salt The salt to use, generally should be large and random
* @param identity The user's identifying information (eg. username)
* @param password The user's password
* @return A new verifier for use in future SRP authentication
*/
public virtual BigInteger GenerateVerifier(byte[] salt, byte[] identity, byte[] password)
{
BigInteger x = Srp6Utilities.CalculateX(digest, N, salt, identity, password);
return g.ModPow(x, N);
}
}
}
#pragma warning restore
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cd68ce3a83ec3c946bf48a047e69fea0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: