private OutgoingMessage sendParameters(final IncomingMessage in) throws KeyAgreementException { final String I = in.readString(); // get s and v for user identified by I // ---------------------------------------------------------------------- final Map credentials; try { final Map userID = new HashMap(); userID.put(Registry.SASL_USERNAME, I); userID.put(SRPRegistry.MD_NAME_FIELD, srp.getAlgorithm()); credentials = passwordDB.lookup(userID); } catch (IOException x) { throw new KeyAgreementException("computeSharedSecret()", x); } final BigInteger s = new BigInteger(1, Util.fromBase64((String) credentials.get(SRPRegistry.SALT_FIELD))); final BigInteger v = new BigInteger( 1, Util.fromBase64((String) credentials.get(SRPRegistry.USER_VERIFIER_FIELD))); final Map configuration; try { final String mode = (String) credentials.get(SRPRegistry.CONFIG_NDX_FIELD); configuration = passwordDB.getConfiguration(mode); } catch (IOException x) { throw new KeyAgreementException("computeSharedSecret()", x); } N = new BigInteger(1, Util.fromBase64((String) configuration.get(SRPRegistry.SHARED_MODULUS))); g = new BigInteger(1, Util.fromBase64((String) configuration.get(SRPRegistry.FIELD_GENERATOR))); // ---------------------------------------------------------------------- // generate an ephemeral keypair final SRPKeyPairGenerator kpg = new SRPKeyPairGenerator(); final Map attributes = new HashMap(); if (rnd != null) { attributes.put(SRPKeyPairGenerator.SOURCE_OF_RANDOMNESS, rnd); } attributes.put(SRPKeyPairGenerator.SHARED_MODULUS, N); attributes.put(SRPKeyPairGenerator.GENERATOR, g); attributes.put(SRPKeyPairGenerator.USER_VERIFIER, v); kpg.setup(attributes); hostKeyPair = kpg.generate(); final BigInteger B = ((SRPPublicKey) hostKeyPair.getPublic()).getY(); final OutgoingMessage result = new OutgoingMessage(); result.writeMPI(N); result.writeMPI(g); result.writeMPI(s); result.writeMPI(B); return result; }
protected OutgoingMessage computeSharedSecret(final IncomingMessage in) throws KeyAgreementException { N = in.readMPI(); g = in.readMPI(); final BigInteger s = in.readMPI(); final BigInteger B = in.readMPI(); if (B.mod(N).equals(BigInteger.ZERO)) { throw new KeyAgreementException("illegal value for B"); } // generate an ephemeral keypair final SRPKeyPairGenerator kpg = new SRPKeyPairGenerator(); final Map attributes = new HashMap(); if (rnd != null) { attributes.put(SRPKeyPairGenerator.SOURCE_OF_RANDOMNESS, rnd); } attributes.put(SRPKeyPairGenerator.SHARED_MODULUS, N); attributes.put(SRPKeyPairGenerator.GENERATOR, g); kpg.setup(attributes); userKeyPair = kpg.generate(); final BigInteger A = ((SRPPublicKey) userKeyPair.getPublic()).getY(); final BigInteger u = uValue(A, B); // u = H(A | B) if (u.mod(N).equals(BigInteger.ZERO)) { throw new KeyAgreementException("u is zero"); } final BigInteger x; try { x = new BigInteger(1, srp.computeX(Util.trim(s), I, p)); } catch (Exception e) { throw new KeyAgreementException("computeSharedSecret()", e); } // compute S = (B - 3g^x) ^ (a + ux) final BigInteger a = ((SRPPrivateKey) userKeyPair.getPrivate()).getX(); final BigInteger S = B.subtract(THREE.multiply(g.modPow(x, N))).modPow(a.add(u.multiply(x)), N); K = S; final OutgoingMessage result = new OutgoingMessage(); result.writeMPI(A); complete = true; return result; }