Skip to content

Instantly share code, notes, and snippets.

@msdousti
Created March 1, 2022 22:54
Show Gist options
  • Save msdousti/31ef4f013ec8dd10d97ee10a0ef9b0dc to your computer and use it in GitHub Desktop.
Save msdousti/31ef4f013ec8dd10d97ee10a0ef9b0dc to your computer and use it in GitHub Desktop.
import org.bouncycastle.crypto.agreement.srp.SRP6Client;
import org.bouncycastle.crypto.agreement.srp.SRP6Server;
import org.bouncycastle.crypto.agreement.srp.SRP6StandardGroups;
import org.bouncycastle.crypto.agreement.srp.SRP6VerifierGenerator;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.util.BigIntegers;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Objects;
public class Main {
public static final Base64.Decoder b64Decoder = Base64.getDecoder();
public static final Base64.Encoder b64Encoder = Base64.getEncoder();
public static void main(String[] args) throws Exception {
byte[] u = strToBytes("3400");
byte[] p = strToBytes("571122");
byte[] salt = b64ToBytes("JE3T3PETRMLVgciyj/0snQ==");
SRP6Client client = new SRP6Client();
SRP6Server server = new SRP6Server();
SRP6VerifierGenerator gen = new SRP6VerifierGenerator();
gen.init(SRP6StandardGroups.rfc5054_2048, new SHA256Digest());
BigInteger v = gen.generateVerifier(salt, u, p);
client.init(SRP6StandardGroups.rfc5054_2048, new SHA256Digest(), new SecureRandom());
server.init(SRP6StandardGroups.rfc5054_2048, v, new SHA256Digest(), new SecureRandom());
BigInteger A = client.generateClientCredentials(salt, u, p);
BigInteger B = server.generateServerCredentials();
System.out.print("-----------------------------------------------------\n");
printClientSecret(client);
printServerSecret(server);
System.out.print("-----------------------------------------------------\n\n");
System.out.printf("v = %s\n\n", bigIntToBase64(v));
System.out.printf("A = %s\n\n", bigIntToBase64(A));
System.out.printf("B = %s\n\n", bigIntToBase64(B));
BigInteger clientS = client.calculateSecret(B);
System.out.printf("clientS = %s\n\n", bigIntToBase64(clientS));
BigInteger M1 = client.calculateClientEvidenceMessage();
System.out.printf("M1 = %s\n\n", bigIntToBase64(M1));
BigInteger serverS = server.calculateSecret(A);
System.out.printf("serverS = %s\n\n", bigIntToBase64(serverS));
if (!server.verifyClientEvidenceMessage(M1))
throw new RuntimeException("Client not verified!");
BigInteger M2 = server.calculateServerEvidenceMessage();
System.out.printf("M2 = %s\n\n", bigIntToBase64(M2));
if (!client.verifyServerEvidenceMessage(M2))
throw new RuntimeException("Server not verified!");
BigInteger sk1 = server.calculateSessionKey();
BigInteger sk2 = client.calculateSessionKey();
if (!Objects.equals(sk1, sk2))
throw new RuntimeException("Server not verified!");
System.out.printf("Shared session key = %s\n\n", bigIntToBase64(sk1));
}
private static void printClientSecret(SRP6Client client) throws Exception {
Field privateField = client.getClass().getDeclaredField("a");
privateField.setAccessible(true);
BigInteger a = (BigInteger) privateField.get(client);
System.out.printf("a = %s\n", bigIntToBase64(a));
}
private static void printServerSecret(SRP6Server server) throws Exception {
Field privateField = server.getClass().getDeclaredField("b");
privateField.setAccessible(true);
BigInteger b = (BigInteger) privateField.get(server);
System.out.printf("b = %s\n", bigIntToBase64(b));
}
public static byte[] b64ToBytes(String s) {
return b64Decoder.decode(strToBytes(s));
}
public static byte[] strToBytes(String s) {
return s.getBytes(StandardCharsets.UTF_8);
}
public static String bigIntToBase64(BigInteger bi) {
return b64Encoder.encodeToString(BigIntegers.asUnsignedByteArray(bi));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment