Mercurial > 510Connectbot
comparison src/com/trilead/ssh2/crypto/dh/DhExchange.java @ 0:0ce5cc452d02
initial version
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 22 May 2014 10:41:19 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0ce5cc452d02 |
---|---|
1 /** | |
2 * | |
3 */ | |
4 package com.trilead.ssh2.crypto.dh; | |
5 | |
6 import java.io.IOException; | |
7 import java.math.BigInteger; | |
8 import java.security.InvalidAlgorithmParameterException; | |
9 import java.security.InvalidKeyException; | |
10 import java.security.KeyFactory; | |
11 import java.security.KeyPair; | |
12 import java.security.KeyPairGenerator; | |
13 import java.security.NoSuchAlgorithmException; | |
14 import java.security.spec.InvalidKeySpecException; | |
15 | |
16 import javax.crypto.KeyAgreement; | |
17 import javax.crypto.interfaces.DHPrivateKey; | |
18 import javax.crypto.interfaces.DHPublicKey; | |
19 import javax.crypto.spec.DHParameterSpec; | |
20 import javax.crypto.spec.DHPublicKeySpec; | |
21 | |
22 /** | |
23 * @author kenny | |
24 * | |
25 */ | |
26 public class DhExchange extends GenericDhExchange { | |
27 | |
28 /* Given by the standard */ | |
29 | |
30 private static final BigInteger P1 = new BigInteger( | |
31 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" | |
32 + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" | |
33 + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" | |
34 + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" | |
35 + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" | |
36 + "FFFFFFFFFFFFFFFF", 16); | |
37 | |
38 private static final BigInteger P14 = new BigInteger( | |
39 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" | |
40 + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" | |
41 + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" | |
42 + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" | |
43 + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" | |
44 + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" | |
45 + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" | |
46 + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" | |
47 + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" | |
48 + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" | |
49 + "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16); | |
50 | |
51 private static final BigInteger G = BigInteger.valueOf(2); | |
52 | |
53 /* Client public and private */ | |
54 | |
55 private DHPrivateKey clientPrivate; | |
56 private DHPublicKey clientPublic; | |
57 | |
58 /* Server public */ | |
59 | |
60 private DHPublicKey serverPublic; | |
61 | |
62 @Override | |
63 public void init(String name) throws IOException { | |
64 final DHParameterSpec spec; | |
65 | |
66 if ("diffie-hellman-group1-sha1".equals(name)) { | |
67 spec = new DHParameterSpec(P1, G); | |
68 } | |
69 else if ("diffie-hellman-group14-sha1".equals(name)) { | |
70 spec = new DHParameterSpec(P14, G); | |
71 } | |
72 else { | |
73 throw new IllegalArgumentException("Unknown DH group " + name); | |
74 } | |
75 | |
76 try { | |
77 KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH"); | |
78 kpg.initialize(spec); | |
79 KeyPair pair = kpg.generateKeyPair(); | |
80 clientPrivate = (DHPrivateKey) pair.getPrivate(); | |
81 clientPublic = (DHPublicKey) pair.getPublic(); | |
82 } | |
83 catch (NoSuchAlgorithmException e) { | |
84 throw(IOException) new IOException("No DH keypair generator").initCause(e); | |
85 } | |
86 catch (InvalidAlgorithmParameterException e) { | |
87 throw(IOException) new IOException("Invalid DH parameters").initCause(e); | |
88 } | |
89 } | |
90 | |
91 @Override | |
92 public byte[] getE() { | |
93 if (clientPublic == null) | |
94 throw new IllegalStateException("DhExchange not initialized!"); | |
95 | |
96 return clientPublic.getY().toByteArray(); | |
97 } | |
98 | |
99 @Override | |
100 protected byte[] getServerE() { | |
101 if (serverPublic == null) | |
102 throw new IllegalStateException("DhExchange not initialized!"); | |
103 | |
104 return serverPublic.getY().toByteArray(); | |
105 } | |
106 | |
107 @Override | |
108 public void setF(byte[] f) throws IOException { | |
109 if (clientPublic == null) | |
110 throw new IllegalStateException("DhExchange not initialized!"); | |
111 | |
112 final KeyAgreement ka; | |
113 | |
114 try { | |
115 KeyFactory kf = KeyFactory.getInstance("DH"); | |
116 DHParameterSpec params = clientPublic.getParams(); | |
117 this.serverPublic = (DHPublicKey) kf.generatePublic(new DHPublicKeySpec( | |
118 new BigInteger(f), params.getP(), params.getG())); | |
119 ka = KeyAgreement.getInstance("DH"); | |
120 ka.init(clientPrivate); | |
121 ka.doPhase(serverPublic, true); | |
122 } | |
123 catch (NoSuchAlgorithmException e) { | |
124 throw(IOException) new IOException("No DH key agreement method").initCause(e); | |
125 } | |
126 catch (InvalidKeyException e) { | |
127 throw(IOException) new IOException("Invalid DH key").initCause(e); | |
128 } | |
129 catch (InvalidKeySpecException e) { | |
130 throw(IOException) new IOException("Invalid DH key").initCause(e); | |
131 } | |
132 | |
133 sharedSecret = new BigInteger(ka.generateSecret()); | |
134 } | |
135 | |
136 @Override | |
137 public String getHashAlgo() { | |
138 return "SHA1"; | |
139 } | |
140 } |