aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/agreement/srp/SRP6Server.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/agreement/srp/SRP6Server.java')
-rw-r--r--libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/agreement/srp/SRP6Server.java90
1 files changed, 90 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/agreement/srp/SRP6Server.java b/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/agreement/srp/SRP6Server.java
new file mode 100644
index 000000000..50f6f7cea
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/agreement/srp/SRP6Server.java
@@ -0,0 +1,90 @@
+package org.spongycastle.crypto.agreement.srp;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import org.spongycastle.crypto.CryptoException;
+import org.spongycastle.crypto.Digest;
+
+/**
+ * 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 Digest digest;
+
+ protected BigInteger A;
+
+ protected BigInteger b;
+ protected BigInteger B;
+
+ protected BigInteger u;
+ protected BigInteger S;
+
+ 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 void init(BigInteger N, BigInteger g, BigInteger v, Digest digest, SecureRandom random)
+ {
+ this.N = N;
+ this.g = g;
+ this.v = v;
+
+ this.random = random;
+ this.digest = digest;
+ }
+
+ /**
+ * Generates the server's credentials that are to be sent to the client.
+ * @return The server's public value to the client
+ */
+ public BigInteger generateServerCredentials()
+ {
+ BigInteger k = SRP6Util.calculateK(digest, N, g);
+ this.b = selectPrivateValue();
+ this.B = k.multiply(v).mod(N).add(g.modPow(b, N)).mod(N);
+
+ return B;
+ }
+
+ /**
+ * 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 BigInteger calculateSecret(BigInteger clientA) throws CryptoException
+ {
+ this.A = SRP6Util.validatePublicValue(N, clientA);
+ this.u = SRP6Util.calculateU(digest, N, A, B);
+ this.S = calculateS();
+
+ return S;
+ }
+
+ protected BigInteger selectPrivateValue()
+ {
+ return SRP6Util.generatePrivateValue(digest, N, g, random);
+ }
+
+ private BigInteger calculateS()
+ {
+ return v.modPow(u, N).multiply(A).mod(N).modPow(b, N);
+ }
+}