1 20 21 22 23 24 25 package org.snmp4j.security; 26 27 import javax.crypto.*; 28 29 import org.snmp4j.log.*; 30 import javax.crypto.spec.IvParameterSpec; 31 import javax.crypto.spec.SecretKeySpec; 32 import org.snmp4j.smi.OctetString; 33 34 35 44 public abstract class PrivAES 45 implements PrivacyProtocol { 46 47 private static final int DECRYPT_PARAMS_LENGTH = 8; 48 49 private static final LogAdapter logger = LogFactory.getLogger(PrivAES.class); 50 private int keyBytes; 51 protected Salt salt; 52 53 61 public PrivAES(int keyBytes) { 62 if ((keyBytes != 16) && (keyBytes != 24) && (keyBytes != 32)) { 63 throw new IllegalArgumentException ( 64 "Only 128, 192 and 256 bit AES is allowed. Requested (" 65 + (8 * keyBytes) + ")."); 66 } 67 this.keyBytes = keyBytes; 68 this.salt = Salt.getInstance(); 69 } 70 71 public byte[] encrypt(byte[] unencryptedData, int offset, int length, 72 byte[] encryptionKey, long engineBoots, 73 long engineTime, DecryptParams decryptParams) { 74 75 byte[] initVect = new byte[16]; 76 long my_salt = salt.getNext(); 77 78 if (encryptionKey.length < keyBytes) { 79 throw new IllegalArgumentException ( 80 "Needed key length is " + keyBytes + ". Got only " + encryptionKey.length + 81 "."); 82 } 83 84 if ((decryptParams.array == null) || 85 (decryptParams.length < DECRYPT_PARAMS_LENGTH)) { 86 decryptParams.array = new byte[DECRYPT_PARAMS_LENGTH]; 87 } 88 decryptParams.length = DECRYPT_PARAMS_LENGTH; 89 decryptParams.offset = 0; 90 91 92 initVect[0] = (byte) ( (engineBoots >> 24) & 0xFF); 93 initVect[1] = (byte) ( (engineBoots >> 16) & 0xFF); 94 initVect[2] = (byte) ( (engineBoots >> 8) & 0xFF); 95 initVect[3] = (byte) ( (engineBoots) & 0xFF); 96 initVect[4] = (byte) ( (engineTime >> 24) & 0xFF); 97 initVect[5] = (byte) ( (engineTime >> 16) & 0xFF); 98 initVect[6] = (byte) ( (engineTime >> 8) & 0xFF); 99 initVect[7] = (byte) ( (engineTime) & 0xFF); 100 for (int i = 56, j = 8; i >= 0; i -= 8, j++) { 101 initVect[j] = (byte) ( (my_salt >> i) & 0xFF); 102 } 103 for (int i = 0; i < 8; i++) { 104 decryptParams.array[i] = initVect[i + 8]; 105 } 106 if (logger.isDebugEnabled()) { 107 logger.debug("initVect is " + asHex(initVect)); 108 } 109 110 byte[] encryptedData = null; 112 try { 113 Cipher alg = Cipher.getInstance("AES/CFB/NoPadding"); 115 SecretKeySpec key = 116 new SecretKeySpec(encryptionKey, 0, keyBytes, "AES"); 117 IvParameterSpec ivSpec = new IvParameterSpec(initVect); 118 alg.init(Cipher.ENCRYPT_MODE, key, ivSpec); 119 encryptedData = alg.doFinal(unencryptedData, offset, length); 120 121 if (logger.isDebugEnabled()) { 122 logger.debug("aes encrypt: Data to encrypt " + asHex(unencryptedData)); 123 124 logger.debug("aes encrypt: used key " + asHex(encryptionKey)); 125 126 logger.debug("aes encrypt: created privacy_params " + 127 asHex(decryptParams.array)); 128 129 logger.debug("aes encrypt: encrypted Data " + 130 asHex(encryptedData)); 131 } 132 } 133 catch (Exception e) { 134 logger.error("Encrypt Exception " + e); 135 } 136 137 return encryptedData; 138 } 139 140 public byte[] decrypt(byte[] cryptedData, int offset, int length, 141 byte[] decryptionKey, long engineBoots, long engineTime, 142 DecryptParams decryptParams) { 143 144 byte[] initVect = new byte[16]; 145 146 if (decryptionKey.length < keyBytes) { 147 throw new IllegalArgumentException ( 148 "Needed key length is " + keyBytes + ". Got only " + decryptionKey.length + 149 "."); 150 } 151 152 153 initVect[0] = (byte) ( (engineBoots >> 24) & 0xFF); 154 initVect[1] = (byte) ( (engineBoots >> 16) & 0xFF); 155 initVect[2] = (byte) ( (engineBoots >> 8) & 0xFF); 156 initVect[3] = (byte) ( (engineBoots) & 0xFF); 157 initVect[4] = (byte) ( (engineTime >> 24) & 0xFF); 158 initVect[5] = (byte) ( (engineTime >> 16) & 0xFF); 159 initVect[6] = (byte) ( (engineTime >> 8) & 0xFF); 160 initVect[7] = (byte) ( (engineTime) & 0xFF); 161 for (int i = 0; i < 8; i++) { 162 initVect[i + 8] = decryptParams.array[i + decryptParams.offset]; 163 164 } 165 if (logger.isDebugEnabled()) { 166 logger.debug("initVect is " + asHex(initVect)); 167 } 168 169 byte[] decryptedData = null; 170 try { 171 Cipher alg = Cipher.getInstance("AES/CFB/NoPadding"); 173 SecretKeySpec key = 174 new SecretKeySpec(decryptionKey, 0, keyBytes, "AES"); 175 IvParameterSpec ivSpec = new IvParameterSpec(initVect); 176 alg.init(Cipher.DECRYPT_MODE, key, ivSpec); 177 decryptedData = alg.doFinal(cryptedData, offset, length); 178 179 if (logger.isDebugEnabled()) { 180 logger.debug("aes decrypt: Data to decrypt " + asHex(cryptedData)); 181 182 logger.debug("aes decrypt: used key " + asHex(decryptionKey)); 183 184 logger.debug("aes decrypt: used privacy_params " + 185 asHex(decryptParams.array)); 186 187 logger.debug("aes decrypt: decrypted Data " + 188 asHex(decryptedData)); 189 } 190 } 191 catch (Exception e) { 192 logger.error("Decrypt Exception " + e); 193 } 194 195 return decryptedData; 196 } 197 198 public int getEncryptedLength(int scopedPDULength) { 199 return scopedPDULength; 200 } 201 202 208 public static String asHex(byte buf[]) { 209 return new OctetString(buf).toHexString(); 210 } 211 212 public int getMinKeyLength() { 213 return keyBytes; 214 } 215 216 public int getMaxKeyLength() { 217 return getMinKeyLength(); 218 } 219 220 public int getDecryptParamsLength() { 221 return DECRYPT_PARAMS_LENGTH; 222 } 223 } 224 | Popular Tags |