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 } |