Omaha #3226 fixed lightning decrypt validation, added initialization vector
Change-Id: I8c72ef66f3f65a5bb1c3fdf8a2dd391c0cb5c554 Former-commit-id:0f2fde3d29
[formerly9064c50f01
] [formerlyda6eea7f57
] [formerly0f2fde3d29
[formerly9064c50f01
] [formerlyda6eea7f57
] [formerly36f8207246
[formerlyda6eea7f57
[formerly 38a729b7d5b42ac60004473a4c875b5171a93569]]]] Former-commit-id:36f8207246
Former-commit-id:a228a4490c
[formerlyb5bc5cf85b
] [formerly 2c3c9a4018b4c62754a3d190903cf70fc8bbdbb8 [formerlybb69af4aef
]] Former-commit-id: 874b9a4b5813b66cb67f27f0976d76c3e68f095c [formerly18fd0db668
] Former-commit-id:2ad045e4c7
This commit is contained in:
parent
44c246c0a8
commit
c428d36577
5 changed files with 132 additions and 11 deletions
|
@ -22,6 +22,7 @@ package com.raytheon.edex.plugin.binlightning;
|
|||
import gov.noaa.nws.ost.edex.plugin.binlightning.BinLightningAESKey;
|
||||
import gov.noaa.nws.ost.edex.plugin.binlightning.BinLightningDataDecryptionException;
|
||||
import gov.noaa.nws.ost.edex.plugin.binlightning.BinLightningDecoderUtil;
|
||||
import gov.noaa.nws.ost.edex.plugin.binlightning.DecryptedLightningValidator;
|
||||
import gov.noaa.nws.ost.edex.plugin.binlightning.EncryptedBinLightningCipher;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -88,6 +89,7 @@ import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
|||
* Jun 05, 2014 3226 bclement LightningStikePoint refactor, added extractPData()
|
||||
* Jun 09, 2014 3226 bclement moved data array decrypt prep to EncryptedBinLightingCipher
|
||||
* Jun 10, 2014 3226 bclement added filter support
|
||||
* Jun 19, 2014 3226 bclement added validator callback
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -114,6 +116,23 @@ public class BinLightningDecoder extends AbstractDecoder {
|
|||
|
||||
private String traceId = null;
|
||||
|
||||
/**
|
||||
* callback for validating decryption results
|
||||
*/
|
||||
private static DecryptedLightningValidator validator = new DecryptedLightningValidator() {
|
||||
@Override
|
||||
public boolean isValid(byte[] decryptedData) {
|
||||
return BinLightningDecoderUtil.isKeepAliveRecord(decryptedData) == false
|
||||
&& BinLightningDecoderUtil
|
||||
.isLightningDataRecords(decryptedData) == false;
|
||||
/*
|
||||
* use this if keep-alive record could be mixed with lightning
|
||||
* records
|
||||
*/
|
||||
// return BinLigntningDecoderUtil.isValidMixedRecordData(decryptedData) == false
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a BinLightning decoder. Calling hasNext() after construction
|
||||
* will return false, decode() will return a null.
|
||||
|
@ -351,7 +370,7 @@ public class BinLightningDecoder extends AbstractDecoder {
|
|||
.prepDataForDecryption(pdata, traceId);
|
||||
|
||||
byte[] decryptedData = cipher.decryptData(encryptedData,
|
||||
dataDate, BINLIGHTNING_KEYSTORE_PREFIX);
|
||||
dataDate, BINLIGHTNING_KEYSTORE_PREFIX, validator);
|
||||
// decrypt ok, then decode, first check if keep-alive record
|
||||
if (BinLightningDecoderUtil.isKeepAliveRecord(decryptedData)) {
|
||||
logger.info(traceId
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
**/
|
||||
package com.raytheon.edex.plugin.binlightning.total;
|
||||
|
||||
import gov.noaa.nws.ost.edex.plugin.binlightning.DecryptedLightningValidator;
|
||||
import gov.noaa.nws.ost.edex.plugin.binlightning.EncryptedBinLightningCipher;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -58,6 +59,7 @@ import com.raytheon.uf.common.wmo.WMOTimeParser;
|
|||
* May 30, 2014 3226 bclement Initial creation
|
||||
* Jun 09, 2014 3226 bclement added encryption support
|
||||
* Jun 10, 2014 3226 bclement added filter support
|
||||
* Jun 19, 2014 3226 bclement added validator callback
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -101,6 +103,13 @@ public class TotalLightningDecoder {
|
|||
|
||||
public static final String TOTAL_LIGHTNING_KEYSTORE_PREFIX = "total.lightning";
|
||||
|
||||
private static final DecryptedLightningValidator validator = new DecryptedLightningValidator() {
|
||||
@Override
|
||||
public boolean isValid(byte[] data) {
|
||||
return validFlashPacket(data, COMBINATION_PACKET_HEADER_SIZE);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse total lightning data into BinLightningRecords
|
||||
*
|
||||
|
@ -219,7 +228,7 @@ public class TotalLightningDecoder {
|
|||
fileName);
|
||||
try {
|
||||
return CIPHER.decryptData(pdata, baseTime.getTime(),
|
||||
TOTAL_LIGHTNING_KEYSTORE_PREFIX);
|
||||
TOTAL_LIGHTNING_KEYSTORE_PREFIX, validator);
|
||||
} catch (Exception e) {
|
||||
throw new DecoderException("Problem decrypting total lightning", e);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.Key;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
|
@ -29,6 +32,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
|
||||
|
@ -47,6 +52,7 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
* 20130503 DCS 112 Wufeng Zhou To handle both the new encrypted data and legacy bit-shifted data
|
||||
* Jun 03, 2014 3226 bclement moved from com.raytheon.edex.plugin.binlightning to gov.noaa.nws.ost.edex.plugin.binlightning
|
||||
* Jun 09, 2014 3226 bclement refactored to support multiple stores for different data types
|
||||
* Jun 19, 2014 3226 bclement added getInitializationVector()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -67,6 +73,8 @@ public class BinLightningAESKey {
|
|||
|
||||
public static final String CIPHER_ALGORITHM_SUFFIX = ".cipherAlgorithm";
|
||||
|
||||
public static final String CIPHER_INITIALIZATION_VECTOR_SUFFIX = ".initializationVectorFile";
|
||||
|
||||
public static final String DEFAULT_CIPHER_ALGORITHM = "AES";
|
||||
|
||||
private static final String CONF_PROPERTIES_FILE = "BinLightningAESKey.properties";
|
||||
|
@ -313,6 +321,32 @@ public class BinLightningAESKey {
|
|||
DEFAULT_CIPHER_ALGORITHM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Cipher initialization vector parameter spec for data type
|
||||
*
|
||||
* @param propertyPrefix
|
||||
* prefix for properties associated with a particular lightning
|
||||
* data type
|
||||
* @return null if not found or error occurred
|
||||
*/
|
||||
public static IvParameterSpec getInitializationVector(String propertyPrefix) {
|
||||
IvParameterSpec rval = null;
|
||||
String ivFileName = props.getProperty(propertyPrefix
|
||||
+ CIPHER_INITIALIZATION_VECTOR_SUFFIX);
|
||||
if (ivFileName != null) {
|
||||
Path ivPath = Paths.get(ivFileName);
|
||||
try {
|
||||
byte[] ivData = Files.readAllBytes(ivPath);
|
||||
rval = new IvParameterSpec(ivData);
|
||||
} catch (IOException e) {
|
||||
logger.error(
|
||||
"Unable to create initialization vector for type: "
|
||||
+ propertyPrefix, e);
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
private String alias;
|
||||
private Key key;
|
||||
private Date keyDate;
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package gov.noaa.nws.ost.edex.plugin.binlightning;
|
||||
|
||||
/**
|
||||
* Callback to validate results of lightning data decryption
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 18, 2014 3226 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface DecryptedLightningValidator {
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* @return true if data is valid
|
||||
*/
|
||||
public boolean isValid(byte[] data);
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
|
@ -37,6 +38,7 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
* Jun 03, 2014 3226 bclement moved from com.raytheon.edex.plugin.binlightning to gov.noaa.nws.ost.edex.plugin.binlightning
|
||||
* handled null return from BinLightningAESKey.getBinLightningAESKeys()
|
||||
* Jun 09, 2014 3226 bclement refactored to support multiple stores for different data types
|
||||
* Jun 19, 2014 3226 bclement added validator callback, added initialization vector support
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -88,15 +90,21 @@ public class EncryptedBinLightningCipher {
|
|||
if (keys == null) {
|
||||
keys = new BinLightningAESKey[0];
|
||||
}
|
||||
String algorithm = BinLightningAESKey
|
||||
.getCipherAlgorithm(propertyPrefix);
|
||||
IvParameterSpec iv = BinLightningAESKey
|
||||
.getInitializationVector(propertyPrefix);
|
||||
HashMap<String, Cipher> cipherMap = new HashMap<String, Cipher>();
|
||||
for (BinLightningAESKey key : keys) {
|
||||
try {
|
||||
SecretKeySpec skeySpec = (SecretKeySpec) key.getKey();
|
||||
String algorithm = BinLightningAESKey
|
||||
.getCipherAlgorithm(propertyPrefix);
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
|
||||
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
if (iv != null) {
|
||||
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
|
||||
} else {
|
||||
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
|
||||
}
|
||||
cipherMap.put(key.getAlias(), cipher);
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
|
@ -120,14 +128,17 @@ public class EncryptedBinLightningCipher {
|
|||
* @param data
|
||||
* @param propertyPrefix
|
||||
* prefix for lightning type configuration
|
||||
* @param validator
|
||||
* used to validate decrypted data
|
||||
* @return
|
||||
* @throws IllegalBlockSizeException
|
||||
* @throws BadPaddingException
|
||||
*/
|
||||
public byte[] decryptData(byte[] data, String propertyPrefix)
|
||||
public byte[] decryptData(byte[] data, String propertyPrefix,
|
||||
DecryptedLightningValidator validator)
|
||||
throws IllegalBlockSizeException, BadPaddingException,
|
||||
BinLightningDataDecryptionException {
|
||||
return decryptData(data, null, propertyPrefix);
|
||||
return decryptData(data, null, propertyPrefix, validator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,11 +149,14 @@ public class EncryptedBinLightningCipher {
|
|||
* @param dataDate
|
||||
* @param propertyPrefix
|
||||
* prefix for lightning type configuration
|
||||
* @param validator
|
||||
* used to validate decrypted data
|
||||
* @return
|
||||
* @throws IllegalBlockSizeException
|
||||
* @throws BadPaddingException
|
||||
*/
|
||||
public byte[] decryptData(byte[] data, Date dataDate, String propertyPrefix)
|
||||
public byte[] decryptData(byte[] data, Date dataDate,
|
||||
String propertyPrefix, DecryptedLightningValidator validator)
|
||||
throws IllegalBlockSizeException, BadPaddingException,
|
||||
BinLightningDataDecryptionException {
|
||||
if (data == null) {
|
||||
|
@ -179,8 +193,7 @@ public class EncryptedBinLightningCipher {
|
|||
|
||||
// wrong key will decrypt data into random noise/garbage, so we need to do a sanity check to make sure
|
||||
// we are decrypting with the right key
|
||||
if ( BinLightningDecoderUtil.isKeepAliveRecord(decryptedData) == false && BinLightningDecoderUtil.isLightningDataRecords(decryptedData) == false) {
|
||||
//if (BinLigntningDecoderUtil.isValidMixedRecordData(decryptedData) == false) { // use this only if keep-alive record could be mixed with lightning records
|
||||
if (!validator.isValid(decryptedData)) {
|
||||
throw new BinLightningDataDecryptionException("Decrypted data (" + decryptedData.length + " bytes) with key "
|
||||
+ alias
|
||||
+ " is not valid keep-alive or binLightning records.",
|
||||
|
|
Loading…
Add table
Reference in a new issue