JavacardOS will not accept order any more, please contact our partner Feitian online Store:
https://ftsafe.en.alibaba.com/index.html
https://ftsafe.en.alibaba.com/index.html
How to compute MAC
Moderator: UNKNwYSHSA
How to compute MAC
Hi, everyone.
I need to implement authentication process. How can I compute the MAC data?
Thanks
I need to implement authentication process. How can I compute the MAC data?
Thanks
- UNKNwYSHSA
- Posts: 630
- Joined: Thu May 21, 2015 4:05 am
- Points :3055
- Contact:
Re: How to compute MAC
What's the code you write for?
The specification usually describe how to calculate the MAC step by step for details.
For example, the GP specification, has figure and text description for how to calculate MAC, very clear while writing code.
The specification usually describe how to calculate the MAC step by step for details.
For example, the GP specification, has figure and text description for how to calculate MAC, very clear while writing code.
sense and simplicity
- UNKNwYSHSA
- Posts: 630
- Joined: Thu May 21, 2015 4:05 am
- Points :3055
- Contact:
Re: How to compute MAC
Like this:
You do not have the required permissions to view the files attached to this post. Please login first.
sense and simplicity
Re: How to compute MAC
Here is an example of how to do the MAC. It comes from oracle community.
Note:
icv is set to 00:00:00:00:00:00:00:00 for the external authenticate call and the resulting icv from each command is used as the ICV for the next command.
sessionCMAC is the session MAC key
singledesCMAC is left half (8 bytes) of the session MAC key.
Here is some code to derive a key from derivation data.
The MAC method for verifying the card and host cryptogram is different to the retail MAC used for EXTERNAL AUTHENTICATE. Here is some code to generate the signature for host and card cryptograms.
Code: Select all
byte[] mac;
byte[] icv = new byte[8];
Cipher desedeCBCCipher = Cipher.getInstance("DESede/CBC/NoPadding");
Cipher desCipher = Cipher.getInstance("DES/CBC/NoPadding");
IvParameterSpec ivSpec = new IvParameterSpec(icv);
if (data.length % 8 != 0)
throw new Exception("data block size must be multiple of 8");
int blocks = data.length / 8;
for (int i = 0; i < blocks - 1; i++) {
desCipher.init(Cipher.ENCRYPT_MODE, singledesCMAC, ivSpec);
byte[] block = desCipher.doFinal(data, i * 8, 8);
ivSpec = new IvParameterSpec(block);
}
int offset = (blocks - 1) * 8;
desedeCBCCipher.init(Cipher.ENCRYPT_MODE, sessionCMAC, ivSpec);
mac = desedeCBCCipher.doFinal(data, offset, 8);
ivSpec = new IvParameterSpec(new byte[8]);
desCipher.init(Cipher.ENCRYPT_MODE, singledesCMAC, ivSpec);
icv = desCipher.doFinal(data);
Note:
icv is set to 00:00:00:00:00:00:00:00 for the external authenticate call and the resulting icv from each command is used as the ICV for the next command.
sessionCMAC is the session MAC key
singledesCMAC is left half (8 bytes) of the session MAC key.
Here is some code to derive a key from derivation data.
Code: Select all
private SecretKey getSecretKey(byte[] keyData) throws GeneralSecurityException {
if (keyData.length == 16) {
byte[] temp = (byte[]) keyData.clone();
keyData = new byte[24];
System.arraycopy(temp, 0, keyData, 0, temp.length);
System.arraycopy(temp, 0, keyData, 16, 8);
}
DESedeKeySpec keySpec = new DESedeKeySpec(keyData);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey key = secretKeyFactory.generateSecret(keySpec);
return key;
}
private Key deriveKey(byte[] keyData, byte[] data) throws GeneralSecurityException {
Key key = getSecretKey(keyData);
IvParameterSpec dps = new IvParameterSpec(DEFAULT_ICV);
desedeCBCCipher.init(Cipher.ENCRYPT_MODE, key, dps);
byte[] result = desedeCBCCipher.doFinal(data);
adjustParity(result);
return getSecretKey(result);
}
/**
* Adjust a DES key to odd parity
*
* @param key
* to be adjusted
*/
private static void adjustParity(byte[] key) {
for (int i = 0; i < key.length; i++) {
int akku = (key[i] & 0xFF) | 1;
for (int c = 7; c > 0; c--) {
akku = (akku & 1) ^ (akku >> 1);
}
key[i] = (byte) ((key[i] & 0xFE) | akku);
}
}
The MAC method for verifying the card and host cryptogram is different to the retail MAC used for EXTERNAL AUTHENTICATE. Here is some code to generate the signature for host and card cryptograms.
Code: Select all
/**
* Calculate the DES CBC MAC using the standard cipher algorithms
*
* @param key
* Key used for MAC calculation
* @param data
* Data to calculate the MAC for
* @param iv
* ICV
*
* @returns CBC MAC
*/
public byte[] cbcMac(byte[] data) throws AuthenticationException {
byte[] temp;
try {
Cipher cbcDES = Cipher.getInstance("DESede/CBC/NoPadding");
IvParameterSpec params = new IvParameterSpec(DEFAULT_ICV);
cbcDES.init(Cipher.ENCRYPT_MODE, sessionSENC, params);
temp = cbcDES.doFinal(data);
} catch (GeneralSecurityException e) {
throw new AuthenticationException("Error performing CBC MAC", e);
}
byte[] signature = new byte[8];
System.arraycopy(temp, temp.length - 8, signature, 0, signature.length);
return signature;
}
Re: How to compute MAC
Hello!
Thank you very much for these code examples. Please allow me ask a couple of questions regarding these code examples:
1. Is the sessionCMAC calculated using the KeyGenerator.getInstance("DESede") ?
2. I am not very sure how to calculate the singledesCMAC out of sessionCMAC...Can I do it this way?
private static byte[] getHalfKey(byte[] doubleDesKey)
{
byte[] singledesCMAC = new byte[8];
System.arraycopy(doubleDesKey, doubleDesKey.length - 8, singledesCMAC, 0, singledesCMAC.length);
return singledesCMAC;
}
and then convert these bytes to a secret key this way?
byte[] halfAKeyBytes = getHalfKey(master_mac_key.getEncoded());
KeySpec halfKeySpec = new DESedeKeySpec(halfAKeyBytes);
SecretKey halfAKey = mySecretKeyFactory.generateSecret(myKeySpec);
Also, in the method: private SecretKey getSecretKey(byte[] keyData), what exactly is derivation data? Is it another key? or is it how we actually derive the singledesCMAC out of sessionCMAC?
Thank you very much!
Thank you very much for these code examples. Please allow me ask a couple of questions regarding these code examples:
1. Is the sessionCMAC calculated using the KeyGenerator.getInstance("DESede") ?
2. I am not very sure how to calculate the singledesCMAC out of sessionCMAC...Can I do it this way?
private static byte[] getHalfKey(byte[] doubleDesKey)
{
byte[] singledesCMAC = new byte[8];
System.arraycopy(doubleDesKey, doubleDesKey.length - 8, singledesCMAC, 0, singledesCMAC.length);
return singledesCMAC;
}
and then convert these bytes to a secret key this way?
byte[] halfAKeyBytes = getHalfKey(master_mac_key.getEncoded());
KeySpec halfKeySpec = new DESedeKeySpec(halfAKeyBytes);
SecretKey halfAKey = mySecretKeyFactory.generateSecret(myKeySpec);
Also, in the method: private SecretKey getSecretKey(byte[] keyData), what exactly is derivation data? Is it another key? or is it how we actually derive the singledesCMAC out of sessionCMAC?
Thank you very much!
- UNKNwYSHSA
- Posts: 630
- Joined: Thu May 21, 2015 4:05 am
- Points :3055
- Contact:
Re: How to compute MAC
I was looking for Retail MAC Calculation when I came across this discussion.
- UNKNwYSHSA
- Posts: 630
- Joined: Thu May 21, 2015 4:05 am
- Points :3055
- Contact:
Re: How to compute MAC
You can refer source code of bouncycastle. Refer to implementation of class org.bouncycastle.crypto.macs.ISO9797Alg3Mac.
That can resolve all your questions.
For your 1st question: The DESede algorithm can only be used on the output transformation (last transformation).
That can resolve all your questions.
For your 1st question: The DESede algorithm can only be used on the output transformation (last transformation).
sense and simplicity
-
- Posts: 6
- Joined: Fri Jul 07, 2017 12:22 pm
- Points :110
- Contact:
Re: How to compute MAC
Hello
i need some clarification on C-MAC if any one can guide.
my init update and ext auth work ok
after external auth i got ICV last verified with ext auth in output of external auth
now on next i plan to implement delete AID
i have to use same ICV where for next msg ?
i am testing on JCIDE with exmple
data = "84E400800A4F" + "08" + aiddata
results1 = des(data,S_MAChalf ) question is ICV use on this or next one ?
results2 = 3des(data+8,S_MAC)
my output return 69 82 i know i made mistake some where on C-MAC but documents do not explain perfectly nor any sample to understand this.
i need some clarification on C-MAC if any one can guide.
my init update and ext auth work ok
after external auth i got ICV last verified with ext auth in output of external auth
now on next i plan to implement delete AID
i have to use same ICV where for next msg ?
i am testing on JCIDE with exmple
data = "84E400800A4F" + "08" + aiddata
results1 = des(data,S_MAChalf ) question is ICV use on this or next one ?
results2 = 3des(data+8,S_MAC)
my output return 69 82 i know i made mistake some where on C-MAC but documents do not explain perfectly nor any sample to understand this.
Re: How to compute MAC
According to GPC_Specification_v2.2.1, the ICV should be the MAC of the EXTERNAL AUTHENTICATE command.
The description from GPC_Specification_v2.2.1 is :
E.3.2 Message Integrity ICV using Explicit Secure Channel Initiation
When using explicit Secure Channel initiation, SCP02 mandates the use of a MAC on the EXTERNAL AUTHENTICATE command.
For the EXTERNAL AUTHENTICATE command MAC verification, the ICV is set to zero.
Once successfully verified, the MAC of the EXTERNAL AUTHENTICATE command becomes the ICV for the subsequent C-MAC verification and/or R-MAC generation.
I hole that would be useful for you.
The description from GPC_Specification_v2.2.1 is :
E.3.2 Message Integrity ICV using Explicit Secure Channel Initiation
When using explicit Secure Channel initiation, SCP02 mandates the use of a MAC on the EXTERNAL AUTHENTICATE command.
For the EXTERNAL AUTHENTICATE command MAC verification, the ICV is set to zero.
Once successfully verified, the MAC of the EXTERNAL AUTHENTICATE command becomes the ICV for the subsequent C-MAC verification and/or R-MAC generation.
I hole that would be useful for you.
Who is online
Users browsing this forum: No registered users and 25 guests