5776630 [rkeene@sledge /home/rkeene/archive/floydssh/ssh]$ cat -n SshCrypto.java
  1 /*
  2  * This file is part of "The Java Telnet Application".
  3  *
  4  * (c) Matthias L. Jugel, Marcus Meißner 1996-2002. All Rights Reserved.
  5  * The file was changed by Radek Polak to work as midlet in MIDP 1.0
  6  *
  7  * Please visit http://javatelnet.org/ for updates and contact.
  8  *
  9  * --LICENSE NOTICE--
 10  * This program is free software; you can redistribute it and/or
 11  * modify it under the terms of the GNU General Public License
 12  * as published by the Free Software Foundation; either version 2
 13  * of the License, or (at your option) any later version.
 14  *
 15  * This program is distributed in the hope that it will be useful,
 16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18  * GNU General Public License for more details.
 19  *
 20  * You should have received a copy of the GNU General Public License
 21  * along with this program; if not, write to the Free Software
 22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 23  * --LICENSE NOTICE--
 24  */
 25 package ssh;
 26 
 27 /**
 28  * @author Marcus Meissner
 29  * @version $Id: SshCrypto.java,v 1.4 2002/10/26 07:15:59 leo Exp $
 30  */
 31 public class SshCrypto {
 32   private Cipher sndCipher,rcvCipher;
 33 
 34   public SshCrypto(String type, final byte[] key) {
 35     sndCipher = Cipher.getInstance(type);
 36     rcvCipher = Cipher.getInstance(type);
 37 
 38     // must be async for RC4. But we currently don't.
 39 
 40     sndCipher.setKey(key);
 41     rcvCipher.setKey(key);
 42   }
 43 
 44   public byte[] encrypt(byte[] block) {
 45     return sndCipher.encrypt(block);
 46   }
 47 
 48   public byte[] decrypt(byte[] block) {
 49     return rcvCipher.decrypt(block);
 50   };
 51 
 52   //-------------------------------------------------------------------------
 53 
 54   static public byte[] encrypteRSAPkcs1Twice(byte[] clearData,
 55                                              byte
 56     [] server_key_public_exponent,
 57                                              byte[] server_key_public_modulus,
 58                                              byte[] host_key_public_exponent,
 59                                              byte[] host_key_public_modulus) {
 60 
 61     // At each encryption step, a multiple-precision integer is constructed
 62     //
 63     // the integer is interpreted as a sequence of bytes, msb first;
 64     // the number of bytes is the number of bytes needed to represent the modulus.
 65     //
 66     // cf PKCS #1: RSA Encryption Standard.  Available for anonymous ftp at ftp.rsa.com.
 67     //  The sequence of byte is as follows:
 68     // The most significant byte is zero.
 69     // The next byte contains the value 2 (stands for public-key encrypted data)
 70     // Then, there are non zero random bytes to fill any unused space
 71     // a zero byte,
 72     // and the data to be encrypted
 73 
 74 
 75     byte[] EncryptionBlock; //what will be encrypted
 76 
 77     int offset = 0;
 78     EncryptionBlock = new byte[server_key_public_modulus.length];
 79     EncryptionBlock[0] = 0;
 80     EncryptionBlock[1] = 2;
 81     offset = 2;
 82     for (int i = 2; i < (EncryptionBlock.length - clearData.length - 1); i++)
 83       EncryptionBlock[offset++] = SshMisc.getNotZeroRandomByte();
 84     EncryptionBlock[offset++] = 0;
 85     for (int i = 0; i < clearData.length; i++)
 86       EncryptionBlock[offset++] = clearData[i];
 87 
 88     //EncryptionBlock can be encrypted now !
 89     BigInteger m, e, message;
 90     byte[] messageByte;
 91 
 92 
 93     m = new BigInteger(server_key_public_modulus);
 94     e = new BigInteger(server_key_public_exponent);
 95     message = new BigInteger(EncryptionBlock);
 96     //      byte[] messageByteOld1 = message.toByteArray();
 97 
 98     message = message.modPow(e, m); //RSA Encryption !!
 99 
100     byte[] messageByteTemp = message.toByteArray(); //messageByte holds the encypted data.
101     //there should be no zeroes a the begining but we have to fix it (JDK bug !!)
102     messageByte = new byte[server_key_public_modulus.length];
103     int tempOffset = 0;
104     while (messageByteTemp[tempOffset] == 0)
105       tempOffset++;
106     for (int i = messageByte.length - messageByteTemp.length + tempOffset;
107          i < messageByte.length; i++)
108       messageByte[i] = messageByteTemp[tempOffset++];
109 
110 
111     // we can't check that the crypted message is OK : no way to decrypt :-(
112 
113     //according to the ssh source  !!!!! Not well explained in the protocol!!!
114     clearData = messageByte;
115 
116     //SECOND ROUND !!
117 
118     offset = 0;
119     EncryptionBlock = new byte[host_key_public_modulus.length];
120     EncryptionBlock[0] = 0;
121     EncryptionBlock[1] = 2;
122 
123     offset = 2;
124     for (int i = 2; i < (EncryptionBlock.length - clearData.length - 1); i++)
125       EncryptionBlock[offset++] = SshMisc.getNotZeroRandomByte();   //random !=0
126     EncryptionBlock[offset++] = 0;
127     for (int i = 0; i < clearData.length; i++)
128       EncryptionBlock[offset++] = clearData[i];
129 
130     //EncryptionBlock can be encrypted now !
131 
132     m = new BigInteger(host_key_public_modulus);
133     e = new BigInteger(host_key_public_exponent);
134     message = new BigInteger(EncryptionBlock);
135 
136     message = message.modPow(e, m);
137 
138     messageByteTemp = message.toByteArray();    //messageByte holds the encypted data.
139     //there should be no zeroes a the begining but we have to fix it (JDK bug !!)
140     messageByte = new byte[host_key_public_modulus.length];
141     tempOffset = 0;
142     while (messageByteTemp[tempOffset] == 0)
143       tempOffset++;
144     for (int i = messageByte.length - messageByteTemp.length + tempOffset;
145          i < messageByte.length; i++)
146       messageByte[i] = messageByteTemp[tempOffset++];
147 
148     //Second encrypted key : encrypted_session_key //mp-int
149     byte[] encrypted_session_key = new byte[host_key_public_modulus.length + 2];    //encrypted_session_key is a mp-int
	!!!
150 
151     //the lengh of the mp-int.
152 
153     encrypted_session_key[1] = (byte) ((8 * host_key_public_modulus.length) & 0xff);
154 
155     encrypted_session_key[0] = (byte) (((8 * host_key_public_modulus.length) >> 8) & 0xff);
156     //the mp-int
157     for (int i = 0; i < host_key_public_modulus.length; i++)
158       encrypted_session_key[i + 2] = messageByte[i];
159     return encrypted_session_key;
160   };
161 }
5776631 [rkeene@sledge /home/rkeene/archive/floydssh/ssh]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-03-06 22:44:06