validate that ccn lengths match BINs

This commit is contained in:
millmanorama 2017-09-25 21:09:15 +02:00
parent 795a4677e7
commit a6c76a1100
8 changed files with 107 additions and 11 deletions

View File

@ -16,7 +16,7 @@
<dependency conf="autopsy_core->*" org="org.jbundle.thin.base.screen" name="jcalendarbutton" rev="1.4.6"/> <dependency conf="autopsy_core->*" org="org.jbundle.thin.base.screen" name="jcalendarbutton" rev="1.4.6"/>
<!-- commmon --> <!-- commmon -->
<dependency org="com.google.guava" name="guava" rev="19.0"/> <dependency org="com.google.guava" name="guava" rev="21.0"/>
<dependency conf="autopsy_core->*" org="org.apache.commons" name="commons-lang3" rev="3.0"/> <dependency conf="autopsy_core->*" org="org.apache.commons" name="commons-lang3" rev="3.0"/>
<dependency conf="autopsy_core->*" org="org.apache.commons" name="commons-csv" rev="1.4"/> <dependency conf="autopsy_core->*" org="org.apache.commons" name="commons-csv" rev="1.4"/>

View File

@ -24,7 +24,7 @@ file.reference.dom4j-1.6.1.jar=release/modules/ext/dom4j-1.6.1.jar
file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.1_spec-1.0.jar file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.1_spec-1.0.jar
file.reference.gson-1.4.jar=release/modules/ext/gson-1.4.jar file.reference.gson-1.4.jar=release/modules/ext/gson-1.4.jar
file.reference.gstreamer-java-1.5.jar=release/modules/ext/gstreamer-java-1.5.jar file.reference.gstreamer-java-1.5.jar=release/modules/ext/gstreamer-java-1.5.jar
file.reference.guava-19.0.jar=release/modules/ext/guava-19.0.jar file.reference.guava-21.0.jar=release/modules/ext/guava-21.0.jar
file.reference.imageio-bmp-3.2.jar=release/modules/ext/imageio-bmp-3.2.jar file.reference.imageio-bmp-3.2.jar=release/modules/ext/imageio-bmp-3.2.jar
file.reference.imageio-core-3.2.jar=release/modules/ext/imageio-core-3.2.jar file.reference.imageio-core-3.2.jar=release/modules/ext/imageio-core-3.2.jar
file.reference.imageio-icns-3.2.jar=release/modules/ext/imageio-icns-3.2.jar file.reference.imageio-icns-3.2.jar=release/modules/ext/imageio-icns-3.2.jar
@ -78,7 +78,6 @@ javadoc.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-javado
javadoc.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-javadoc.jar javadoc.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-javadoc.jar
javadoc.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-javadoc.jar javadoc.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-javadoc.jar
javadoc.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-javadoc.jar javadoc.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-javadoc.jar
javadoc.reference.guava-19.0.jar=release/modules/ext/guava-19.0-javadoc.jar
javadoc.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-javadoc.jar javadoc.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-javadoc.jar
javadoc.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-javadoc.jar javadoc.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-javadoc.jar
javadoc.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-javadoc.jar javadoc.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-javadoc.jar
@ -87,7 +86,6 @@ source.reference.commons-csv-1.4.jar=release/modules/ext/commons-csv-1.4-sources
source.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-sources.jar source.reference.commons-io-2.5.jar=release/modules/ext/commons-io-2.5-sources.jar
source.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-sources.jar source.reference.compiler-0.9.1.jar=release/modules/ext/compiler-0.9.1-sources.jar
source.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-sources.jar source.reference.controlsfx-8.40.11.jar=release/modules/ext/controlsfx-8.40.11-sources.jar
source.reference.guava-19.0.jar=release/modules/ext/guava-19.0-sources.jar
source.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-sources.jar source.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4-sources.jar
source.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-sources.jar source.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4-sources.jar
source.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-sources.jar source.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4-sources.jar

View File

@ -848,8 +848,8 @@
<binary-origin>release/modules/ext/slf4j-simple-1.6.1.jar</binary-origin> <binary-origin>release/modules/ext/slf4j-simple-1.6.1.jar</binary-origin>
</class-path-extension> </class-path-extension>
<class-path-extension> <class-path-extension>
<runtime-relative-path>ext/guava-19.0.jar</runtime-relative-path> <runtime-relative-path>ext/guava-21.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/guava-19.0.jar</binary-origin> <binary-origin>release/modules/ext/guava-21.0.jar</binary-origin>
</class-path-extension> </class-path-extension>
<class-path-extension> <class-path-extension>
<runtime-relative-path>ext/commons-io-2.5.jar</runtime-relative-path> <runtime-relative-path>ext/commons-io-2.5.jar</runtime-relative-path>

View File

@ -14,6 +14,8 @@
<conf name="servlet"/> <conf name="servlet"/>
</configurations> </configurations>
<dependencies> <dependencies>
<dependency conf="autopsy->*" org="com.google.guava" name="guava" rev="21.0"/>
<!-- Solr --> <!-- Solr -->
<dependency conf="solr-libs->default" org="org.apache.solr" name="solr-cell" rev="4.9.1"/> <dependency conf="solr-libs->default" org="org.apache.solr" name="solr-cell" rev="4.9.1"/>
<dependency conf="solr-war->default" org="org.apache.solr" name="solr" rev="4.9.1" transitive="false" /> <!-- the war file --> <dependency conf="solr-war->default" org="org.apache.solr" name="solr" rev="4.9.1" transitive="false" /> <!-- the war file -->

View File

@ -42,7 +42,7 @@ file.reference.fontbox-2.0.3.jar=release/modules/ext/fontbox-2.0.3.jar
file.reference.geoapi-3.0.0.jar=release/modules/ext/geoapi-3.0.0.jar file.reference.geoapi-3.0.0.jar=release/modules/ext/geoapi-3.0.0.jar
file.reference.grib-4.5.5.jar=release/modules/ext/grib-4.5.5.jar file.reference.grib-4.5.5.jar=release/modules/ext/grib-4.5.5.jar
file.reference.gson-2.2.4.jar=release/modules/ext/gson-2.2.4.jar file.reference.gson-2.2.4.jar=release/modules/ext/gson-2.2.4.jar
file.reference.guava-17.0.jar=release/modules/ext/guava-17.0.jar file.reference.guava-21.0.jar=release/modules/ext/guava-21.0.jar
file.reference.hamcrest-core-1.3.jar=release/modules/ext/hamcrest-core-1.3.jar file.reference.hamcrest-core-1.3.jar=release/modules/ext/hamcrest-core-1.3.jar
file.reference.httpclient-4.3.1.jar=release/modules/ext/httpclient-4.3.1.jar file.reference.httpclient-4.3.1.jar=release/modules/ext/httpclient-4.3.1.jar
file.reference.httpcore-4.3.jar=release/modules/ext/httpcore-4.3.jar file.reference.httpcore-4.3.jar=release/modules/ext/httpcore-4.3.jar

View File

@ -213,10 +213,6 @@
<runtime-relative-path>ext/slf4j-api-1.7.12.jar</runtime-relative-path> <runtime-relative-path>ext/slf4j-api-1.7.12.jar</runtime-relative-path>
<binary-origin>release/modules/ext/slf4j-api-1.7.12.jar</binary-origin> <binary-origin>release/modules/ext/slf4j-api-1.7.12.jar</binary-origin>
</class-path-extension> </class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/guava-17.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/guava-17.0.jar</binary-origin>
</class-path-extension>
<class-path-extension> <class-path-extension>
<runtime-relative-path>ext/opennlp-maxent-3.0.3.jar</runtime-relative-path> <runtime-relative-path>ext/opennlp-maxent-3.0.3.jar</runtime-relative-path>
<binary-origin>release/modules/ext/opennlp-maxent-3.0.3.jar</binary-origin> <binary-origin>release/modules/ext/opennlp-maxent-3.0.3.jar</binary-origin>
@ -677,6 +673,10 @@
<runtime-relative-path>ext/sis-storage-0.6.jar</runtime-relative-path> <runtime-relative-path>ext/sis-storage-0.6.jar</runtime-relative-path>
<binary-origin>release/modules/ext/sis-storage-0.6.jar</binary-origin> <binary-origin>release/modules/ext/sis-storage-0.6.jar</binary-origin>
</class-path-extension> </class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/guava-21.0.jar</runtime-relative-path>
<binary-origin>ext/guava-21.0.jar</binary-origin>
</class-path-extension>
<class-path-extension> <class-path-extension>
<runtime-relative-path>ext/jcip-annotations-1.0.jar</runtime-relative-path> <runtime-relative-path>ext/jcip-annotations-1.0.jar</runtime-relative-path>
<binary-origin>release/modules/ext/jcip-annotations-1.0.jar</binary-origin> <binary-origin>release/modules/ext/jcip-annotations-1.0.jar</binary-origin>

View File

@ -19,6 +19,11 @@
package org.sleuthkit.autopsy.keywordsearch; package org.sleuthkit.autopsy.keywordsearch;
import com.google.common.base.CharMatcher; import com.google.common.base.CharMatcher;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range;
import com.google.common.collect.RangeMap;
import com.google.common.collect.TreeRangeMap;
import java.util.Set;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit; import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit;
@ -42,6 +47,73 @@ final class CreditCardValidator {
private static final LuhnCheckDigit CREDIT_CARD_NUM_LUHN_CHECK = new LuhnCheckDigit(); private static final LuhnCheckDigit CREDIT_CARD_NUM_LUHN_CHECK = new LuhnCheckDigit();
/**
* map from ccn IIN to allowed lengths
*/
static private final RangeMap<Integer, Set<Integer>> allowedLengths = TreeRangeMap.create();
private static final ImmutableSet<Integer> Set12to19 = ImmutableSet.of(12, 13, 14, 15, 16, 17, 18, 19);
private static final ImmutableSet<Integer> Set14to19 = ImmutableSet.of(14, 15, 16, 17, 18, 19);
private static final ImmutableSet<Integer> Set16to19 = ImmutableSet.of(16, 17, 18, 29);
static {
//amex
allowedLengths.put(Range.closedOpen(34000000, 35000000), ImmutableSet.of(15));
allowedLengths.put(Range.closedOpen(37000000, 38000000), ImmutableSet.of(15));
//visa
allowedLengths.put(Range.closedOpen(40000000, 50000000), Set12to19);
//visa electron
allowedLengths.put(Range.closedOpen(40260000, 40270000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(41750000, 41750100), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(44050000, 44060000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(45080000, 45090000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(48440000, 48450000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(49130000, 49140000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(49170000, 49180000), ImmutableSet.of(16));
//China UnionPay
allowedLengths.put(Range.closedOpen(62000000, 63000000), Set16to19);
//MasterCard
allowedLengths.put(Range.closedOpen(51000000, 56000000), ImmutableSet.of(16));
allowedLengths.put(Range.closedOpen(22210000, 27210000), ImmutableSet.of(16));
//Verve, these over lap with discover
allowedLengths.put(Range.closedOpen(50609900, 50619900), ImmutableSet.of(16, 19));
allowedLengths.put(Range.closedOpen(65000200, 65002700), ImmutableSet.of(16, 19));
//Maestro
allowedLengths.put(Range.closedOpen(50000000, 50100000), Set12to19);
allowedLengths.put(Range.closedOpen(56000000, 59000000), Set12to19);
allowedLengths.put(Range.closedOpen(60000000, 70000000), Set12to19);
allowedLengths.put(Range.closedOpen(63900000, 63910000), Set12to19);
allowedLengths.put(Range.closedOpen(67000000, 68000000), Set12to19);
//Diners Club International (processed by discover
allowedLengths.put(Range.closedOpen(30000000, 30600000), Set16to19);
allowedLengths.put(Range.closedOpen(30950000, 30960000), Set16to19);
allowedLengths.put(Range.closedOpen(36000000, 37000000), Set14to19);
allowedLengths.put(Range.closedOpen(38000000, 40000000), Set16to19);
//Diners Club USA & Canada (MasterCard co brand)
allowedLengths.put(Range.closedOpen(54000000, 56000000), Set14to19);
//Discover
allowedLengths.put(Range.closedOpen(60110000, 60120000), Set16to19);
allowedLengths.put(Range.closedOpen(62212600, 62292600), Set16to19);
allowedLengths.put(Range.closedOpen(64400000, 66000000), Set16to19);
//JCB //process by discover
allowedLengths.put(Range.closedOpen(35280000, 35900000), Set16to19);
//Dankort
allowedLengths.put(Range.closedOpen(50190000, 50200000), Set16to19);
//InterPayment
allowedLengths.put(Range.closedOpen(63600000, 63700000), Set16to19);
}
/** /**
* Does the given string represent a valid credit card number? It must have * Does the given string represent a valid credit card number? It must have
* no separators, or only '-', or only ' '. Checks digit grouping for * no separators, or only '-', or only ' '. Checks digit grouping for
@ -79,6 +151,10 @@ final class CreditCardValidator {
splitCCN = new String[]{cannonicalCCN}; splitCCN = new String[]{cannonicalCCN};
} }
if (false == lengthMatchesBin(cannonicalCCN)) {
return false;
}
// validate digit grouping for 15, 16, and 19 digit cards // validate digit grouping for 15, 16, and 19 digit cards
switch (cannonicalCCN.length()) { switch (cannonicalCCN.length()) {
case 15: case 15:
@ -105,6 +181,12 @@ final class CreditCardValidator {
return CREDIT_CARD_NUM_LUHN_CHECK.isValid(cannonicalCCN); return CREDIT_CARD_NUM_LUHN_CHECK.isValid(cannonicalCCN);
} }
private boolean lengthMatchesBin(String cannonicalCCN) {
String BIN = cannonicalCCN.substring(0, 8);
final Set<Integer> lengthsForBIN = allowedLengths.get(Integer.valueOf(BIN));
return null == lengthsForBIN || lengthsForBIN.contains(cannonicalCCN.length());
}
static private boolean isValidOtherDigitGrouping(String[] splitCCN) { static private boolean isValidOtherDigitGrouping(String[] splitCCN) {
if (splitCCN.length == 1) { if (splitCCN.length == 1) {
return true; return true;

View File

@ -46,6 +46,18 @@ public class CreditCardValidatorTest {
public void tearDown() { public void tearDown() {
} }
@Test
public void testLengthMatchesBin(){
System.out.println("lengthMatchesBin");
CreditCardValidator validator = new CreditCardValidator();
//amex must be 15
assertEquals(true, validator.isValidCCN("3431 136294 58529"));
assertEquals(false, validator.isValidCCN("3431-136294-5850"));
assertEquals(false, validator.isValidCCN("34311362945850"));
assertEquals(false, validator.isValidCCN("3431 1362 9458 5034"));
}
/** /**
* Test of isValidCCN method, of class CreditCardValidator. * Test of isValidCCN method, of class CreditCardValidator.
*/ */
@ -187,4 +199,6 @@ public class CreditCardValidatorTest {
assertEquals(false, CreditCardValidator.isValidCCN("123 456789031")); //grouping assertEquals(false, CreditCardValidator.isValidCCN("123 456789031")); //grouping
assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031")); //separators assertEquals(false, CreditCardValidator.isValidCCN("1234-56789 031")); //separators
} }
} }