Ejemplo n.º 1
0
        /// <summary>
        /// Calculates and returns the key material.
        /// A session key must be derived from this key material using a secure key derivation function (KDF).
        /// The KDF used to derive the key is handled externally (i.e. not by JPakeParticipant).
        ///
        /// The keying material will be identical for each participant if and only if
        /// each participant's password is the same.  i.e. If the participants do not
        /// share the same password, then each participant will derive a different key.
        /// Therefore, if you immediately start using a key derived from
        /// the keying material, then you must handle detection of incorrect keys.
        /// If you want to handle this detection explicitly, you can optionally perform
        /// rounds 3 and 4.  See JPakeParticipant for details on how to execute
        /// rounds 3 and 4.
        ///
        /// The keying material will be in the range <tt>[0, p-1]</tt>.
        ///
        /// ValidateRound2PayloadReceived(JPakeRound2Payload) must be called prior to this method.
        /// 
        /// As a side effect, the internal password array is cleared, since it is no longer needed.
        ///
        /// After execution, the State state will be STATE_KEY_CALCULATED.
        ///
        /// Throws InvalidOperationException if called prior to ValidateRound2PayloadReceived(JPakeRound2Payload),
        /// or if called multiple times.
        /// </summary>
        public virtual BigInteger CalculateKeyingMaterial()
        {
            if (this.state >= STATE_KEY_CALCULATED)
                throw new InvalidOperationException("Key already calculated for " + participantId);
            if (this.state < STATE_ROUND_2_VALIDATED)
                throw new InvalidOperationException("Round 2 payload must be validated prior to creating key for " + participantId);

            BigInteger s = JPakeUtilities.CalculateS(password);

            // Clear the password array from memory, since we don't need it anymore.
            // Also set the field to null as a flag to indicate that the key has already been calculated.
            Array.Clear(password, 0, password.Length);
            this.password = null;

            BigInteger keyingMaterial = JPakeUtilities.CalculateKeyingMaterial(p, q, gx4, x2, s, b);

            // Clear the ephemeral private key fields as well.
            // Note that we're relying on the garbage collector to do its job to clean these up.
            // The old objects will hang around in memory until the garbage collector destroys them.
            // 
            // If the ephemeral private keys x1 and x2 are leaked,
            // the attacker might be able to brute-force the password.
            this.x1 = null;
            this.x2 = null;
            this.b = null;

            // Do not clear gx* yet, since those are needed by round 3.

            this.state = STATE_KEY_CALCULATED;

            return keyingMaterial;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates and returns the payload to send to the other participant during round 2.
        ///
        /// ValidateRound1PayloadReceived(JPakeRound1Payload) must be called prior to this method.
        ///
        /// After execution, the State state will be  STATE_ROUND_2_CREATED.
        ///
        /// Throws InvalidOperationException if called prior to ValidateRound1PayloadReceived(JPakeRound1Payload), or multiple times
        /// </summary>
        public virtual JPakeRound2Payload CreateRound2PayloadToSend()
        {
            if (this.state >= STATE_ROUND_2_CREATED)
                throw new InvalidOperationException("Round 2 payload already created for " + this.participantId);
            if (this.state < STATE_ROUND_1_VALIDATED)
                throw new InvalidOperationException("Round 1 payload must be validated prior to creating round 2 payload for " + this.participantId);

            BigInteger gA = JPakeUtilities.CalculateGA(p, gx1, gx3, gx4);
            BigInteger s = JPakeUtilities.CalculateS(password);
            BigInteger x2s = JPakeUtilities.CalculateX2s(q, x2, s);
            BigInteger A = JPakeUtilities.CalculateA(p, q, gA, x2s);
            BigInteger[] knowledgeProofForX2s = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, gA, A, x2s, participantId, digest, random);

            this.state = STATE_ROUND_2_CREATED;

            return new JPakeRound2Payload(participantId, A, knowledgeProofForX2s);
        }
Ejemplo n.º 3
0
        public virtual JPakeRound2Payload CreateRound2PayloadToSend()
        {
            //IL_001d: Unknown result type (might be due to invalid IL or missing references)
            //IL_0040: Unknown result type (might be due to invalid IL or missing references)
            if (state >= STATE_ROUND_2_CREATED)
            {
                throw new InvalidOperationException("Round 2 payload already created for " + participantId);
            }
            if (state < STATE_ROUND_1_VALIDATED)
            {
                throw new InvalidOperationException("Round 1 payload must be validated prior to creating round 2 payload for " + participantId);
            }
            BigInteger gA          = JPakeUtilities.CalculateGA(p, gx1, gx3, gx4);
            BigInteger s           = JPakeUtilities.CalculateS(password);
            BigInteger bigInteger  = JPakeUtilities.CalculateX2s(q, x2, s);
            BigInteger bigInteger2 = JPakeUtilities.CalculateA(p, q, gA, bigInteger);

            BigInteger[] knowledgeProofForX2s = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, gA, bigInteger2, bigInteger, participantId, digest, random);
            state = STATE_ROUND_2_CREATED;
            return(new JPakeRound2Payload(participantId, bigInteger2, knowledgeProofForX2s));
        }
Ejemplo n.º 4
0
        public virtual BigInteger CalculateKeyingMaterial()
        {
            //IL_001d: Unknown result type (might be due to invalid IL or missing references)
            //IL_0040: Unknown result type (might be due to invalid IL or missing references)
            if (state >= STATE_KEY_CALCULATED)
            {
                throw new InvalidOperationException("Key already calculated for " + participantId);
            }
            if (state < STATE_ROUND_2_VALIDATED)
            {
                throw new InvalidOperationException("Round 2 payload must be validated prior to creating key for " + participantId);
            }
            BigInteger s = JPakeUtilities.CalculateS(password);

            global::System.Array.Clear((global::System.Array)password, 0, password.Length);
            password = null;
            BigInteger result = JPakeUtilities.CalculateKeyingMaterial(p, q, gx4, x2, s, b);

            x1    = null;
            x2    = null;
            b     = null;
            state = STATE_KEY_CALCULATED;
            return(result);
        }