org.apache.abdera2.common.security.DHBase.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.abdera2.common.security.DHBase.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  The ASF licenses this file to You
 * under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */
package org.apache.abdera2.common.security;

import java.io.Serializable;
import java.math.BigInteger;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.KeyAgreement;
import javax.crypto.spec.DHParameterSpec;

import org.apache.commons.codec.binary.Base64;

/**
 * Implements the Diffie-Hellman Key Exchange details for both parties Party A: DHContext context_a = new DHContext();
 * String req = context_a.getRequestString(); Party B: DHContext context_b = new DHContext(req); EncryptionOptions
 * options = context_b.getEncryptionOptions(enc); // encrypt String ret = context_b.getResponseString(); Party A:
 * context_a.setPublicKey(ret); EncryptionOptions options = context_a.getEncryptionOptions(enc); // decrypt
 */
public class DHBase implements Serializable {

    private static final long serialVersionUID = 9145945368596071015L;
    BigInteger p = null, g = null;
    int l = 0;
    private KeyPair keyPair;
    private Key publicKey;

    public DHBase() {
        try {
            init();
        } catch (Exception e) {
        }
    }

    public DHBase(String dh) {
        try {
            init(dh);
        } catch (Exception e) {
        }
    }

    protected DHBase(KeyPair keyPair, BigInteger p, BigInteger g, int l) {
        this.keyPair = keyPair;
        this.p = p;
        this.g = g;
        this.l = l;
    }

    public String getRequestString() {
        StringBuilder buf = new StringBuilder();
        buf.append(String.format("DH p=%s, g=%s, k=%s", p.toString(), g.toString(),
                Base64.encodeBase64String(keyPair.getPublic().getEncoded())));
        return buf.toString();
    }

    public String getResponseString() {
        StringBuilder buf = new StringBuilder();
        buf.append(String.format("DH k=%s", Base64.encodeBase64String(keyPair.getPublic().getEncoded())));
        return buf.toString();
    }

    private void init() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException,
            InvalidParameterSpecException, InvalidKeySpecException {
        AlgorithmParameterGenerator pgen = AlgorithmParameterGenerator.getInstance("DH");
        pgen.init(512);
        AlgorithmParameters params = pgen.generateParameters();
        DHParameterSpec dhspec = (DHParameterSpec) params.getParameterSpec(DHParameterSpec.class);
        KeyPairGenerator keypairgen = KeyPairGenerator.getInstance("DH");
        keypairgen.initialize(dhspec);
        keyPair = keypairgen.generateKeyPair();
        p = dhspec.getP();
        g = dhspec.getG();
        l = dhspec.getL();
    }

    private void init(String dh)
            throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeySpecException {
        String[] segments = dh.split("\\s+", 2);
        if (!segments[0].equalsIgnoreCase("DH"))
            throw new IllegalArgumentException();
        String[] params = segments[1].split("\\s*,\\s*");
        byte[] key = null;
        for (String param : params) {
            String name = param.substring(0, param.indexOf("="));
            String value = param.substring(param.indexOf("=") + 1);
            if (name.equalsIgnoreCase("p"))
                p = new BigInteger(value);
            else if (name.equalsIgnoreCase("g"))
                g = new BigInteger(value);
            else if (name.equalsIgnoreCase("k"))
                key = Base64.decodeBase64(value);
        }
        init(p, g, l, key);
    }

    private void init(BigInteger p, BigInteger g, int l, byte[] key)
            throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeySpecException {
        DHParameterSpec spec = new DHParameterSpec(p, g, l);
        KeyPairGenerator keypairgen = KeyPairGenerator.getInstance("DH");
        keypairgen.initialize(spec);
        keyPair = keypairgen.generateKeyPair();
        publicKey = decode(key);
    }

    public KeyPair getKeyPair() {
        return keyPair;
    }

    public Key getPublicKey() {
        return publicKey;
    }

    private Key decode(byte[] key) throws NoSuchAlgorithmException, InvalidKeySpecException {
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
        KeyFactory keyFact = KeyFactory.getInstance("DH");
        return keyFact.generatePublic(x509KeySpec);
    }

    public DHBase setPublicKey(String dh) throws NoSuchAlgorithmException, InvalidKeySpecException {
        String[] segments = dh.split("\\s+", 2);
        if (!segments[0].equalsIgnoreCase("DH"))
            throw new IllegalArgumentException();
        String[] tokens = segments[1].split("\\s*,\\s*");
        byte[] key = null;
        for (String token : tokens) {
            String name = token.substring(0, token.indexOf("="));
            String value = token.substring(token.indexOf("=") + 1);
            if (name.equalsIgnoreCase("k"))
                key = Base64.decodeBase64(value);
        }
        publicKey = decode(key);
        return this;
    }

    public Key generateSecret() throws NoSuchAlgorithmException, InvalidKeyException {
        KeyAgreement ka = KeyAgreement.getInstance("DH");
        ka.init(keyPair.getPrivate());
        ka.doPhase(publicKey, true);
        return ka.generateSecret("DESede");
    }

    public Key generateSecret(String alg) throws NoSuchAlgorithmException, InvalidKeyException {
        KeyAgreement ka = KeyAgreement.getInstance("DH");
        ka.init(keyPair.getPrivate());
        ka.doPhase(publicKey, true);
        return ka.generateSecret(alg);
    }

}