1 20 21 package org.snmp4j.security; 22 23 import org.snmp4j.smi.OID; 24 import org.snmp4j.log.*; 25 import javax.crypto.spec.SecretKeySpec; 26 import javax.crypto.spec.IvParameterSpec; 27 import javax.crypto.Cipher; 28 29 39 public class PrivDES 40 implements PrivacyProtocol { 41 42 private static final long serialVersionUID = 2526070176429255416L; 43 44 47 public static final OID ID = new OID("1.3.6.1.6.3.10.1.2.2"); 48 49 private static final int DECRYPT_PARAMS_LENGTH = 8; 50 protected Salt salt; 51 52 private static final LogAdapter logger = LogFactory.getLogger(PrivDES.class); 53 54 public PrivDES() 55 { 56 this.salt = Salt.getInstance(); 57 } 58 59 public byte[] encrypt(byte[] unencryptedData, 60 int offset, 61 int length, 62 byte[] encryptionKey, 63 long engineBoots, 64 long engineTime, 65 DecryptParams decryptParams) { 66 int mySalt = (int)salt.getNext(); 67 68 if (encryptionKey.length < 16) { 69 logger.error("Wrong Key length: need at least 16 bytes, is " + 70 encryptionKey.length + 71 " bytes."); 72 throw new IllegalArgumentException ("encryptionKey has illegal length " 73 + encryptionKey.length 74 + " (should be at least 16)."); 75 } 76 77 if ( (decryptParams.array == null) || (decryptParams.length < 8)) { 78 decryptParams.array = new byte[8]; 79 } 80 decryptParams.length = 8; 81 decryptParams.offset = 0; 82 83 if (logger.isDebugEnabled()) { 85 logger.debug("Preparing decrypt_params."); 86 } 87 for (int i = 0; i < 4; ++i) { 88 decryptParams.array[3 - i] = (byte) (0xFF & (engineBoots >> (8 * i))); 89 decryptParams.array[7 - i] = (byte) (0xFF & (mySalt >> (8 * i))); 90 } 91 92 byte[] iv = new byte[8]; 93 94 if (logger.isDebugEnabled()) { 96 logger.debug("Preparing iv for encryption."); 97 } 98 for (int i = 0; i < 8; ++i) { 99 iv[i] = (byte) (encryptionKey[8 + i] ^ decryptParams.array[i]); 100 } 101 102 byte[] encryptedData = null; 103 104 try { 105 Cipher alg = Cipher.getInstance("DES/CBC/NoPadding"); 107 SecretKeySpec key = 108 new SecretKeySpec(encryptionKey, 0, 8, "DES"); 109 IvParameterSpec ivSpec = new IvParameterSpec(iv); 110 alg.init(Cipher.ENCRYPT_MODE, key, ivSpec); 111 112 if (length % 8 == 0) { 114 encryptedData = alg.doFinal(unencryptedData, offset, length); 115 } 116 else { 117 if (logger.isDebugEnabled()) { 118 logger.debug("Using padding."); 119 } 120 121 encryptedData = new byte[8 * ( (length / 8) + 1)]; 122 byte[] tmp = new byte[8]; 123 124 int encryptedLength = alg.update(unencryptedData, offset, length, 125 encryptedData); 126 encryptedLength += alg.doFinal(tmp, 0, 8 - (length % 8), 127 encryptedData, encryptedLength); 128 } 129 } 130 catch (Exception e) { 131 logger.error(e); 132 if (logger.isDebugEnabled()) { 133 e.printStackTrace(); 134 } 135 } 136 137 if (logger.isDebugEnabled()) { 138 logger.debug("Encryption finished."); 139 } 140 return encryptedData; 141 } 142 143 156 public byte[] decrypt(byte[] cryptedData, 157 int offset, 158 int length, 159 byte[] decryptionKey, 160 long engineBoots, 161 long engineTime, 162 DecryptParams decryptParams) { 163 if ( (length % 8 != 0) || 164 (length < 8) || 165 (decryptParams.length != 8)) { 166 throw new IllegalArgumentException ("Length (" + length + 167 ")is not multiple of 8 or decrypt params has not length 8 (" 168 + decryptParams.length + ")."); 169 } 170 if (decryptionKey.length < 16) { 171 logger.error("Wrong Key length: need at least 16 bytes, is " + 172 decryptionKey.length + 173 " bytes."); 174 throw new IllegalArgumentException ("decryptionKey has illegal length " 175 + decryptionKey.length 176 + " (should be at least 16)."); 177 } 178 179 byte[] iv = new byte[8]; 180 181 for (int i = 0; i < 8; ++i) { 183 iv[i] = (byte) (decryptionKey[8 + i] ^ decryptParams.array[i]); 184 } 185 186 byte[] decryptedData = null; 187 try { 188 Cipher alg = Cipher.getInstance("DES/CBC/NoPadding"); 190 SecretKeySpec key = 191 new SecretKeySpec(decryptionKey, 0, 8, "DES"); 192 IvParameterSpec ivSpec = new IvParameterSpec(iv); 193 alg.init(Cipher.DECRYPT_MODE, key, ivSpec); 194 decryptedData = alg.doFinal(cryptedData, offset, length); 195 } 196 catch (Exception e) { 197 logger.error(e); 198 if (logger.isDebugEnabled()) { 199 e.printStackTrace(); 200 } 201 } 202 203 return decryptedData; 204 } 205 206 211 public OID getID() { 212 return (OID) ID.clone(); 213 } 214 215 public int getEncryptedLength(int scopedPDULength) { 216 if (scopedPDULength % 8 == 0) { 217 return scopedPDULength; 218 } 219 return 8 * ( (scopedPDULength / 8) + 1); 220 } 221 222 public int getMinKeyLength() { 223 return 16; 224 } 225 226 public int getDecryptParamsLength() { 227 return DECRYPT_PARAMS_LENGTH; 228 } 229 230 public int getMaxKeyLength() { 231 return getMinKeyLength(); 232 } 233 234 } 235 | Popular Tags |