1 19 20 package com.sslexplorer.security.pki; 21 22 import java.io.IOException ; 23 import java.security.Key ; 24 import java.security.spec.KeySpec ; 25 26 import javax.crypto.Cipher; 27 import javax.crypto.SecretKeyFactory; 28 import javax.crypto.spec.DESedeKeySpec; 29 import javax.crypto.spec.IvParameterSpec; 30 31 import com.maverick.crypto.digests.Hash; 32 import com.maverick.util.ByteArrayReader; 33 import com.maverick.util.ByteArrayWriter; 34 35 36 41 public class SshtoolsPrivateKeyFormat extends Base64EncodedFileFormat 42 implements SshPrivateKeyFormat { 43 private static String BEGIN = "---- BEGIN SSHTOOLS ENCRYPTED PRIVATE KEY ----"; 44 private static String END = "---- END SSHTOOLS ENCRYPTED PRIVATE KEY ----"; 45 private int cookie = 0x52f37abe; 46 47 53 public SshtoolsPrivateKeyFormat(String subject, String comment) { 54 super(BEGIN, END); 55 setHeaderValue("Subject", subject); 56 setHeaderValue("Comment", comment); 57 } 58 59 62 public SshtoolsPrivateKeyFormat() { 63 super(BEGIN, END); 64 } 65 66 71 public String getFormatType() { 72 return "SSHTools-PrivateKey-" + super.getFormatType(); 73 } 74 75 82 public boolean isPassphraseProtected(byte[] formattedKey) { 83 try { 84 ByteArrayReader bar = new ByteArrayReader(getKeyBlob(formattedKey)); 85 String type = bar.readString(); 86 87 if (type.equals("none")) { 88 return false; 89 } 90 91 if (type.equalsIgnoreCase("3des-cbc")) { 92 return true; 93 } 94 } catch (IOException ioe) { 95 } catch(InvalidKeyException ex) { 96 } 97 98 return false; 99 } 100 101 111 public byte[] decryptKeyblob(byte[] formattedKey, String passphrase) 112 throws InvalidKeyException { 113 try { 114 byte[] keyblob = getKeyBlob(formattedKey); 115 ByteArrayReader bar = new ByteArrayReader(keyblob); 116 String type = bar.readString(); 117 118 if (type.equalsIgnoreCase("3des-cbc")) { 119 byte[] keydata = makePassphraseKey(passphrase); 121 byte[] iv = new byte[8]; 122 123 if (type.equals("3DES-CBC")) { 124 bar.read(iv); 125 } 126 127 keyblob = bar.readBinaryString(); 128 129 Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); 130 KeySpec keyspec = new DESedeKeySpec(keydata); 131 Key key = SecretKeyFactory.getInstance("DESede").generateSecret(keyspec); 132 cipher.init(Cipher.DECRYPT_MODE, key, 133 new IvParameterSpec(iv, 0, cipher.getBlockSize())); 134 135 ByteArrayReader data = new ByteArrayReader(cipher.doFinal( 136 keyblob)); 137 138 if (data.readInt() == cookie) { 139 keyblob = data.readBinaryString(); 140 } else { 141 throw new InvalidKeyException( 142 "The host key is invalid, check the passphrase supplied"); 143 } 144 } else { 145 keyblob = bar.readBinaryString(); 146 } 147 148 return keyblob; 149 } catch (Exception aoe) { 150 throw new InvalidKeyException("Failed to read host key"); 151 } 152 } 153 154 162 public byte[] encryptKeyblob(byte[] keyblob, String passphrase) { 163 try { 164 ByteArrayWriter baw = new ByteArrayWriter(); 165 String type = "none"; 166 167 if (passphrase != null) { 168 if (!passphrase.trim().equals("")) { 169 type = "3DES-CBC"; 171 172 byte[] keydata = makePassphraseKey(passphrase); 174 byte[] iv = new byte[8]; 175 Utils.getRND().nextBytes(iv); 176 177 Cipher cipher = Cipher.getInstance( 178 "DESede/CBC/PKCS5Padding"); 179 KeySpec keyspec = new DESedeKeySpec(keydata); 180 Key key = SecretKeyFactory.getInstance("DESede") 181 .generateSecret(keyspec); 182 cipher.init(Cipher.ENCRYPT_MODE, key, 183 new IvParameterSpec(iv, 0, cipher.getBlockSize())); 184 185 ByteArrayWriter data = new ByteArrayWriter(); 186 baw.writeString(type); 187 baw.write(iv); 188 data.writeInt(cookie); 189 data.writeBinaryString(keyblob); 190 191 baw.writeBinaryString(cipher.doFinal(data.toByteArray())); 193 194 return formatKey(baw.toByteArray()); 195 } 196 } 197 198 baw.writeString(type); 200 201 baw.writeBinaryString(keyblob); 203 204 return formatKey(baw.toByteArray()); 206 } catch (Exception ioe) { 207 return null; 208 } 209 } 210 211 218 public boolean supportsAlgorithm(String algorithm) { 219 return true; 220 } 221 222 private byte[] makePassphraseKey(String passphrase) { 223 Hash md5 = new Hash("MD5"); 225 md5.putBytes(passphrase.getBytes()); 226 227 byte[] key1 = md5.doFinal(); 228 md5.reset(); 229 md5.putBytes(passphrase.getBytes()); 230 md5.putBytes(key1); 231 232 byte[] key2 = md5.doFinal(); 233 byte[] key = new byte[32]; 234 System.arraycopy(key1, 0, key, 0, 16); 235 System.arraycopy(key2, 0, key, 16, 16); 236 237 return key; 238 } 239 } 240 | Popular Tags |