org.kapott.hbci.smartcardio.RSAKeyData Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hbci4j-core Show documentation
Show all versions of hbci4j-core Show documentation
HBCI4j - Home Banking Computer Interface for Java
/**
*
*/
package org.kapott.hbci.smartcardio;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import org.kapott.hbci.exceptions.HBCI_Exception;
/**
* @author axel
*
*/
public class RSAKeyData {
public enum Type {
ENCIPHER(0),
SIGN(1),
DECIPHER(2),
VERIFY(3);
private final int pos;
Type(int pos) {
this.pos = pos;
}
}
private final static Charset CHARSET = Charset.forName("ISO-8859-1");
private final int index;
private final Type type;
private final int status;
private final int keyType;
private final int keyNum;
private final int keyVersion;
private final PublicKey publicKey;
public RSAKeyData(int index, Type type, byte[] keyLogData, byte[] publicKeyData) {
int offset = type.pos * 8;
if (keyLogData.length < offset + 8)
throw new HBCI_Exception("keyLogData too short");
this.index = index;
this.type = type;
this.status = keyLogData[offset];
this.keyType = keyLogData[offset + 1];
this.keyNum = Integer.valueOf(new String(keyLogData, offset + 2, 3, CHARSET).trim());
this.keyVersion = Integer.valueOf(new String(keyLogData, offset + 5, 3, CHARSET).trim());
if (publicKeyData == null || status != 0x10) {
this.publicKey = null;
} else {
if (publicKeyData.length < 0x79)
throw new HBCI_Exception("publicKeyData too short");
byte algoByte = publicKeyData[6];
if ((algoByte & 0x01) == 0)
throw new HBCI_Exception("invalid public key type");
byte modLen = publicKeyData[14];
byte[] modulus = new byte[modLen];
byte[] publicExponent = new byte[3];
if ((algoByte & 0x08) == 0) {
// MSB
System.arraycopy(publicKeyData, 20, modulus, 0, modLen);
System.arraycopy(publicKeyData, 20 + modLen, publicExponent, 0, 3);
} else {
// LSB
for (int n = 0; n < modLen; n++)
modulus[n] = publicKeyData[20 + modLen - 1 - n];
for (int n = 0; n < 3; n++)
publicExponent[n] = publicKeyData[20 + modLen + 3 - 1 - n];
}
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
this.publicKey = keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new HBCI_Exception("no support for RSA available", e);
} catch (InvalidKeySpecException e) {
throw new RuntimeException(e);
}
}
}
public int getIndex() {
return index;
}
public Type getType() {
return type;
}
public int getStatus() {
return status;
}
public int getKeyType() {
return keyType;
}
public int getKeyNum() {
return keyNum;
}
public int getKeyVersion() {
return keyVersion;
}
public PublicKey getPublicKey() {
return publicKey;
}
@Override
public String toString() {
return "index=" + index
+ " type=" + type
+ " keyType=0x" + Integer.toHexString(keyType)
+ " status=0x" + Integer.toHexString(status)
+ " keyNum=" + keyNum
+ " keyVersion=" + keyVersion
+ " publicKey=" + publicKey;
}
}