I want calculate the MAC
with S-MAC
to sign the plain
with single DES plus final triple DES
in Secure Channel
. I tried as follows but is not worked.
Can anyone help me? Thanks.
byte[] mac_iv = ToHexBytes("0000000000000000");
byte[] mac_key = ToHexBytes("C6713F31B8DC1F8905DFECB4065CB81E"); // S-MAC
byte[] mac_plain = BytesAppend(ToHexBytes("8482000010"), ToHexBytes("1122334455667788"));
byte[] mac_cipher = DES_MAC8_ISO9797_M2_ALG3_Encrypt(mac_iv, mac_key, mac_plain);
Debug.Print("\nmac_cipher: " + ToHexString(mac_cipher));
//
private byte[] DES_MAC8_ISO9797_M2_ALG3_Encrypt(byte[] iv, byte[] key, byte[] plain)
{
try
{
// split the 16 byte key into key A and key B
var key1 = new byte[8];
Buffer.BlockCopy(key, 0, key1, 0, key1.Length);
var key2 = new byte[8];
Buffer.BlockCopy(key, 8, key2, 0, key2.Length);
// init DES CBC encryption with key A and an all-zero IV of 8 bytes
DES des = new DESCryptoServiceProvider();
des.Mode = CipherMode.CBC;
des.Padding = PaddingMode.None;
MemoryStream streamOut = new MemoryStream();
CryptoStream streamCrypto = new CryptoStream(streamOut, des.CreateEncryptor(key1, iv), CryptoStreamMode.Write);
// iterate over all full blocks within the message & for each block perform CBC encryption,
// throwing away the result (using the same cipher instance, you need to keep the state after all)
int fullBlocks = plain.Length / 8;
for (int i = 0; i < fullBlocks; i++) {
int off = i * 8;
byte[] block = new byte[off + 8];
Buffer.BlockCopy(plain, off, block, off, block.Length);
streamCrypto.Write(block, 0, block.Length);
streamCrypto.FlushFinalBlock();
}
// create a final block and copy the left over bytes from the message into it
byte[] final_block = new byte[8];
int left = plain.Length % 8;
Buffer.BlockCopy(plain, left, final_block, left, final_block.Length);
// at the next position add the initial padding indicator byte
// ???
// finalize the CBC encryption by encrypting the final block, and keep the result
streamCrypto.Write(final_block, 0, final_block.Length);
streamCrypto.FlushFinalBlock();
byte[] res = streamOut.ToArray();
// perform DES ECB decryption over the result with key B, replacing the result
des.Mode = CipherMode.ECB;
streamCrypto = new CryptoStream(streamOut, des.CreateDecryptor(key2, iv), CryptoStreamMode.Write);
streamCrypto.Write(res, 0, res.Length);
res = streamOut.ToArray();
// peform DES ECB encryption over the result with key A, replacing the result
des.Mode = CipherMode.ECB;
streamCrypto = new CryptoStream(streamOut, des.CreateDecryptor(key1, iv), CryptoStreamMode.Write);
streamCrypto.Write(res, 0, res.Length);
res = streamOut.ToArray();
return res;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return new byte[0];
}