001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.security; 020 021import org.jpos.iso.ISOUtil; 022 023import java.io.PrintStream; 024import java.util.regex.Matcher; 025import java.util.regex.Pattern; 026 027/** 028 * The SecureDESKey class represents: <br> 029 * Single, double or triple length DES keys that are secured by a security module. 030 * This is typically the DES key encrypted under one of the Local Master Keys of the 031 * security module. 032 * <p> 033 * SecureDESKey has an extra property "Key Check Value". It allows assuring that 034 * two SecureDESKeys owned by two different parties map 035 * to the same clear key. This can be a useful manual check for successful key 036 * exchange. 037 * <p> 038 * NOTE: The security of SecureDESKey is totally dependent on the security of 039 * the used security module. 040 * 041 * @author Hani S. Kirollos 042 * @author Robert Demski 043 * @see SMAdapter 044 */ 045public class SecureDESKey extends SecureVariantKey { 046 047 private static final long serialVersionUID = -9145281998779008306L; 048 049 /** 050 * Regular expression pattern representing key type string value. 051 */ 052 protected static final Pattern KEY_TYPE_PATTERN = Pattern.compile("([^:;]*)([:;])?([^:;])?([^:;])?"); 053 054 /** Default constructor. */ 055 public SecureDESKey() { 056 super(); 057 } 058 059 /** 060 * Constructs an SecureDESKey 061 * @param keyLength e.g. LENGTH_DES, LENGTH_DES3_2KEY, LENGTH_DES3_3KEY 062 * @param keyType key-type label (e.g. {@code ZPK}, {@code TMK}) 063 * @param variant LMK variant byte applied during encryption under the LMK 064 * @param scheme key scheme (encryption form) 065 * @param keyBytes DES Key in the secure proprietary format of your security module 066 * @param keyCheckValue 3-byte (or longer) key check value 067 * @see SMAdapter 068 */ 069 public SecureDESKey (short keyLength, String keyType, byte variant, KeyScheme scheme, byte[] keyBytes, 070 byte[] keyCheckValue) { 071 setKeyLength(keyLength); 072 setKeyType(keyType); 073 setVariant(variant); 074 setScheme(scheme); 075 setKeyBytes(keyBytes); 076 setKeyCheckValue(keyCheckValue); 077 } 078 079 /** 080 * Constructs an SecureDESKey 081 * @param keyLength e.g. LENGTH_DES, LENGTH_DES3_2KEY, LENGTH_DES3_3KEY 082 * @param keyType key-type label (e.g. {@code ZPK}, {@code TMK}) 083 * @param keyBytes DES Key in the secure proprietary format of your security module 084 * @param keyCheckValue 3-byte (or longer) key check value 085 * @see SMAdapter 086 */ 087 public SecureDESKey (short keyLength, String keyType, byte[] keyBytes, 088 byte[] keyCheckValue) { 089 setKeyLength(keyLength); 090 setKeyType(keyType); 091 setKeyBytes(keyBytes); 092 setKeyCheckValue(keyCheckValue); 093 getVariant(); //only for set variant with defaults 094 getScheme(); //only set scheme with defaults 095 } 096 097 /** 098 * Constructs an SecureDESKey 099 * @param keyLength e.g. LENGTH_DES, LENGTH_DES3_2KEY, LENGTH_DES3_3KEY 100 * @param keyType key-type label (e.g. {@code ZPK}, {@code TMK}) 101 * @param keyHexString secure key represented as HexString instead of byte[] 102 * @param keyCheckValueHexString key check value represented as HexString instead of byte[] 103 */ 104 public SecureDESKey (short keyLength, String keyType, String keyHexString, 105 String keyCheckValueHexString) { 106 this(keyLength, keyType, ISOUtil.hex2byte(keyHexString), ISOUtil.hex2byte(keyCheckValueHexString)); 107 } 108 109 /** 110 * Constructs an SecureDESKey 111 * @param keyLength e.g. LENGTH_DES, LENGTH_DES3_2KEY, LENGTH_DES3_3KEY 112 * @param keyType key-type label (e.g. {@code ZPK}, {@code TMK}) 113 * @param variant LMK variant byte applied during encryption under the LMK 114 * @param scheme key scheme (encryption form) 115 * @param keyHexString secure key represented as HexString instead of byte[] 116 * @param keyCheckValueHexString key check value represented as HexString instead of byte[] 117 */ 118 public SecureDESKey (short keyLength, String keyType, byte variant, KeyScheme scheme, String keyHexString, 119 String keyCheckValueHexString) { 120 this(keyLength, keyType, variant, scheme, ISOUtil.hex2byte(keyHexString), ISOUtil.hex2byte(keyCheckValueHexString)); 121 } 122 123 @Override 124 public byte getVariant () { 125 if (variant!=null) 126 return variant; 127 /** 128 * Some variant derivation if it hasn't been explicity stated 129 */ 130 variant = 0; 131 Matcher m = KEY_TYPE_PATTERN.matcher(keyType); 132 m.find(); 133 if (m.group(3) != null) 134 try { 135 variant = Byte.valueOf(m.group(3)); 136 } catch (NumberFormatException ex){ 137 throw new NumberFormatException("Value "+m.group(4)+" is not valid key variant"); 138 } 139 return variant; 140 } 141 142 @Override 143 public KeyScheme getScheme () { 144 if (scheme!=null) 145 return scheme; 146 /** 147 * Some scheme derivation if it hasn't been explicity stated 148 */ 149 switch (keyLength){ 150 case SMAdapter.LENGTH_DES: 151 scheme = KeyScheme.Z; break; 152 case SMAdapter.LENGTH_DES3_2KEY: 153 scheme = KeyScheme.X; break; 154 case SMAdapter.LENGTH_DES3_3KEY: 155 scheme = KeyScheme.Y; break; 156 } 157 Matcher m = KEY_TYPE_PATTERN.matcher(keyType); 158 m.find(); 159 if (m.group(4) != null) 160 try { 161 scheme = KeyScheme.valueOf(m.group(4)); 162 } catch (IllegalArgumentException ex){ 163 throw new IllegalArgumentException("Value "+m.group(4)+" is not valid key scheme"); 164 } 165 return scheme; 166 } 167 168 /** 169 * dumps SecureDESKey basic information 170 * @param p a PrintStream usually supplied by Logger 171 * @param indent indention string, usually suppiled by Logger 172 * @see org.jpos.util.Loggeable 173 */ 174 @Override 175 public void dump (PrintStream p, String indent) { 176 String inner = indent + " "; 177 p.print(indent + "<secure-des-key"); 178 p.print(" length=\"" + getKeyLength() + "\""); 179 p.print(" type=\"" + keyType + "\""); 180 p.print(" variant=\"" + getVariant() + "\""); 181 p.print(" scheme=\"" + this.getScheme() + "\""); 182 if (keyName != null) 183 p.print(" name=\"" + keyName + "\""); 184 185 p.println(">"); 186 p.println(inner + "<data>" + ISOUtil.hexString(getKeyBytes()) + "</data>"); 187 p.println(inner + "<check-value>" + ISOUtil.hexString(getKeyCheckValue()) + "</check-value>"); 188 p.println(indent + "</secure-des-key>"); 189 } 190} 191 192 193