Add an applet for encrypting and decrypting data

This commit is contained in:
Manuel Thalmann 2023-11-07 08:40:14 +01:00
parent 2a785ebb16
commit 60df2dc4b9
5 changed files with 164 additions and 4 deletions

12
.vscode/tasks.json vendored
View file

@ -22,6 +22,18 @@
}, },
"problemMatcher": [] "problemMatcher": []
}, },
{
"label": "Flash SecretApplet",
"type": "shell",
"command": "${workspaceFolder}/scripts/flash.cmd",
"options": {
"env": {
"PACKAGE": "hwb1",
"APPLET": "SecretApplet"
}
},
"problemMatcher": []
},
{ {
"label": "Test MyApplet", "label": "Test MyApplet",
"type": "shell", "type": "shell",

View file

@ -16,10 +16,19 @@
<entries> <entries>
<key>src/hwb1/MyApplet.java</key> <key>src/hwb1/MyApplet.java</key>
<value> <value>
<entry>
<key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">IsJavaCardApplet</key>
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">1</value>
</entry>
<entry> <entry>
<key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">AID</key> <key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">AID</key>
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">52C4C7C95C0420</value> <value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">52C4C7C95C0420</value>
</entry> </entry>
</value>
</entries>
<entries>
<key>src/hwb1/SecretApplet.java</key>
<value>
<entry> <entry>
<key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">IsJavaCardApplet</key> <key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">IsJavaCardApplet</key>
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">1</value> <value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">1</value>

View file

@ -1,6 +1,7 @@
-i -i
-classdir ..\bin -classdir ..\bin
-applet 0x52:0xC4:0xC7:0xC9:0x5C:0x04:0x20 hwb1.MyApplet -applet 0x52:0xC4:0xC7:0xC9:0x5C:0x04:0x20 hwb1.MyApplet
-applet 0x52:0xC4:0xC7:0xC9:0x5C:0x82:0x28 hwb1.SecretApplet
-out CAP JCA EXP -out CAP JCA EXP
-d ..\deliverables\hwb1 -d ..\deliverables\hwb1
-debug -debug

View file

@ -1,5 +1,5 @@
#Thu Oct 12 17:03:08 CEST 2023 #Sat Nov 04 21:00:23 CET 2023
SCRIPTGEN_NO_POWER_UP=false
SCRIPTGEN_NO_POWER_DOWN=true
SCRIPTGEN_NO_BANNER=false
SCRIPTGEN_NO_BEGIN_END=false SCRIPTGEN_NO_BEGIN_END=false
SCRIPTGEN_NO_BANNER=false
SCRIPTGEN_NO_POWER_DOWN=true
SCRIPTGEN_NO_POWER_UP=false

View file

@ -0,0 +1,138 @@
/**
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
*
*/
package hwb1;
import javacard.framework.*;
import javacard.security.AESKey;
import javacard.security.CryptoException;
import javacard.security.KeyBuilder;
import javacard.security.Signature;
import javacardx.crypto.Cipher;
/**
* Applet class
*
* @author <user>
*/
public class SecretApplet extends Applet {
private AESKey encryptionKey;
private AESKey macKey;
/**
* Installs this applet.
*
* @param bArray the array containing installation parameters
* @param bOffset the starting offset in bArray
* @param bLength the length in bytes of the parameter data in bArray
*/
public static void install(byte[] bArray, short bOffset, byte bLength) {
new SecretApplet();
}
/**
* Only this class's install method should create the applet object.
*/
protected SecretApplet() {
register();
encryptionKey = initializeKey(new byte[] { 0x59, (byte)0xA3, (byte)0xFA, 0x76, 0x35, 0x40, 0x01, (byte)0x82, (byte)0xA5, (byte)0xC0, (byte)0xAB, (byte)0xE0, 0x1F, 0x30, (byte)0x89, (byte)0xFA });
macKey = initializeKey(new byte[] { 0x58, (byte)0x9F, 0x61, 0x62, (byte)0xBB, 0x10, (byte)0x89, (byte)0xD8, 0x1A, 0x16, (byte)0xD3, 0x2A, 0x3F, 0x06, 0x27, (byte)0xC6 });
}
/**
* Processes an incoming APDU.
*
* @see APDU
* @param apdu the incoming APDU
*/
public void process(APDU apdu) {
short length;
byte[] buffer = apdu.getBuffer();
if (selectingApplet()) {
ISOException.throwIt(ISO7816.SW_NO_ERROR);
} else {
if (buffer[ISO7816.OFFSET_CLA] != (byte)0x80) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
} else {
byte instruction = buffer[ISO7816.OFFSET_INS];
try {
switch (instruction) {
case 0x42:
byte[] encrypted;
length = apdu.setIncomingAndReceive();
if (length > 64) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
} else {
encrypted = new byte[(short)(length + 16)];
Cipher cipher = getEncryptionCipher(Cipher.MODE_ENCRYPT);
cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, length, encrypted, (short)0);
Signature signature = getMACSignature(Signature.MODE_SIGN);
short totalLength = (short)(length + signature.sign(encrypted, (short)0, length, encrypted, length));
apdu.setOutgoing();
apdu.setOutgoingLength(totalLength);
apdu.sendBytesLong(encrypted, (short)0, totalLength);
}
break;
case 0x44:
length = apdu.setIncomingAndReceive();
if (length > 80) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
} else {
Signature signature = getMACSignature(Signature.MODE_VERIFY);
short signatureLength = 16;
short messageLength = (short)(length - signatureLength);
short signatureOffset = (short)(ISO7816.OFFSET_CDATA + messageLength);
if (!signature.verify(buffer, ISO7816.OFFSET_CDATA, messageLength, buffer, signatureOffset, signatureLength)) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
} else {
byte[] decrypted = new byte[messageLength];
Cipher cipher = getEncryptionCipher(Cipher.MODE_DECRYPT);
cipher.doFinal(buffer, ISO7816.OFFSET_CDATA, messageLength, decrypted, (short)0);
apdu.setOutgoing();
apdu.setOutgoingLength(messageLength);
apdu.sendBytesLong(decrypted, (short)0, messageLength);
}
}
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
break;
}
} catch (CryptoException exception) {
ISOException.throwIt((short)(ISO7816.SW_WRONG_LENGTH | exception.getReason()));
}
ISOException.throwIt(ISO7816.SW_NO_ERROR);
}
}
}
protected AESKey initializeKey(byte[] keyBytes) {
AESKey key = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
key.setKey(keyBytes, (short)0);
return key;
}
protected Cipher getEncryptionCipher(byte mode) {
byte[] initializationVector = new byte[] { 0x18, 0x24, 0x57, (byte)0xD6, (byte)0x97, 0x33, 0x69, (byte)0xED, 0x05, 0x4D, 0x6E, 0x14, (byte)0x93, (byte)0xE4, (byte)0xB7, 0x45 };
Cipher cipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
cipher.init(encryptionKey, mode, initializationVector, (short)0, (short)initializationVector.length);
return cipher;
}
protected Signature getMACSignature(byte mode) {
byte[] initializationVector = new byte[] { (byte)0xB6, 0x6C, (byte)0xAC, (byte)0xC7, (byte)0xD6, 0x78, (byte)0x88, 0x18, 0x07, (byte)0x88, (byte)0xA4, 0x27, 0x07, 0x55, 0x50, 0x2A };
Signature signature = Signature.getInstance(Signature.ALG_AES_MAC_128_NOPAD, false);
signature.init(macKey, mode, initializationVector, (short)0, (short)initializationVector.length);
return signature;
}
}