1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.crypto.agreement; 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.math.BigInteger; 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.SecureRandom; 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.CipherParameters; 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.DHParameters; 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.DHPublicKeyParameters; 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.DHPrivateKeyParameters; 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.AsymmetricKeyParameter; 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.ParametersWithRandom; 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a Diffie-Hellman key exchange engine. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * note: This uses MTI/A0 key agreement in order to make the key agreement 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * secure against passive attacks. If you're doing Diffie-Hellman and both 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * parties have long term public keys you should look at using this. For 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * further information have a look at RFC 2631. 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * It's possible to extend this to more than two parties as well, for the moment 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that is left as an exercise for the reader. 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class DHAgreement 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private DHPrivateKeyParameters key; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private DHParameters dhParams; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private BigInteger privateValue; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private SecureRandom random; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void init( 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CipherParameters param) 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AsymmetricKeyParameter kParam; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (param instanceof ParametersWithRandom) 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParametersWithRandom rParam = (ParametersWithRandom)param; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.random = rParam.getRandom(); 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kParam = (AsymmetricKeyParameter)rParam.getParameters(); 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.random = new SecureRandom(); 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kParam = (AsymmetricKeyParameter)param; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(kParam instanceof DHPrivateKeyParameters)) 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("DHEngine expects DHPrivateKeyParameters"); 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.key = (DHPrivateKeyParameters)kParam; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.dhParams = key.getParameters(); 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * calculate our initial message. 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public BigInteger calculateMessage() 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.privateValue = new BigInteger( 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dhParams.getP().bitLength() - 1, 0, random); 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dhParams.getG().modPow(privateValue, dhParams.getP()); 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * given a message from a given party and the coresponding public key 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * calculate the next message in the agreement sequence. In this case 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this will represent the shared secret. 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public BigInteger calculateAgreement( 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DHPublicKeyParameters pub, 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project BigInteger message) 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!pub.getParameters().equals(dhParams)) 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("Diffie-Hellman public key has wrong parameters."); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return message.modPow(key.getX(), dhParams.getP()).multiply(pub.getY().modPow(privateValue, dhParams.getP())).mod(dhParams.getP()); 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 87