Monday, 28 May 2012

PUT KEY command: way to encrypt key data value and get key check value for SCP 02


Key Encryption and Decryption (Card Specification v 2.0.1)

Key encryption is used when transmitting key data to the card and is over and beyond the security level required for the Secure Channel i.e. all DES keys transmitted to a card (PUT KEY command) should be encrypted.

The key encryption process uses the static Key Encryption Key(KEK/DEK) and the encryption method described in section 12.1.3. (ECB mode) As all DES keys are by their very nature a multiple of 8-byte lengths no padding is required for key encryption operations.

The encryption is performed across the key data and the result of each encryption becomes part of the encrypted key data. This encrypted key data becomes part of the clear text data field in the command message.

The on-card decryption of key data, is the exact opposite of the above operation.

Key verification  (Card Specification v 2.0.1)

In order to verify that the card received the correct key, each DES key transmitted to the card in the PUT KEY command has an associated key check value.

The check value generation process uses the clear text key using the encryption method described in section 12.1.3. The data to be encrypted is binary zeroes and as it is defined to be 8 bytes, no padding is required. The encryption is performed across the 8 binary zeroes and only the 3 right most bytes of the result are required as a check value. As with the encrypted keys the check value becomes part of the clear text data field in the command message.

Following the decryption of the keys, on-card verification of the key is achieved by performing the exact same operation as defined above and comparing the 3 right most bytes of the encryption with the check value in the data field.


Log: 

00A4040007A0000001510000SW6111
00C0000011SW6F0F8407A0000001510000A5049F6501FF9000
8050000008BD4E6A713DD7D805SW611C
00C000001CSW00000000000000000000FF0200010C6892C3B73CFE58E93B5ECF185E9000
8482000010B88BB23C01C42F1A49D2357B41AC2E93SW9000
80D8000117218010D09780F8AB1875477824E706C2E208BB0320309BSW9000
00C0000004SW2120309B9000

Way to encrypt key data value and get Key Check Value (SCP 02)

1. get static key(KEK): 

derivation data: 01810001000000000000000000000000
KEK key(DEK):  505152535455565758595A5B5C5D5E5F
//CBC DES:
static key: 8D2FA346ED9E2A4E15E100B07328E7A2

2. get enc data value: 

data value: 404142434445464748494a4b4c4d4e4d (This will be the new key you want to add/change)
static key: 8D2FA346ED9E2A4E15E100B07328E7A2
//ECB DES:
ENCdata: D09780F8AB1875477824E706C2E208BB

3. get check value: 

data value: 0000000000000000
key:  404142434445464748494a4b4c4d4e4d (This will be the new key you want to add/change)
//ECB DES  & get first three bytes.  20309B5AEC51125E:
Key Check Value:  20309B

4. Organise PUT KEY command.

//80D8000117218010+ENCdata+KeyCheckValueLength+KeyCheckValue
80D8000117218010D09780F8AB1875477824E706C2E208BB0320309BSW9000
00C0000004SW2120309B9000

PUT KEY command structure




Thursday, 17 May 2012

Explicit Secure Channel Initiation: Way to calculate authentication cryptogram and CMAC for SCP 02

for details, please refer to GlobalPlatform Card Specification 2.2 - Annex E

A. Brief Introduction 


Usage: 

Explicit Secure Channel initiation allows the off-card entity to instruct the card (EXTERNAL AUTHENTICATE COMMAND) as to what level of security is required for the current Secure Channel and apply this level of security to all the subsequent messages exchanged between the card and the off-card entity until the end of the session.

Flow: 

Figure 1: Explicit Secure Channel initiation Flow

B. Commands Structure

B.1 INITIALIZE UPDATE

Table 1: INITIALIZE UPDATE command structure
Key Version Number: defines Key Version Number within the Secure Domain (SD) to be used to initiate the Secure Channel Session. If this value = 0x00, the first available key chosen by SD will be used.

Host challenge: randomly generated number

Response Message:
Table 2: INITIALIZE UPDATE command Response Message

B.2 EXTERNAL AUTHENTICATE 

Table 3: EXTERNAL AUTHENTICATE command structure
Host cryptogram: 8 bytes 
MAC: 8 bytes
Security Level: 
Table 4: Security Level coding

C. Way to calculate authentication cryptogram and CMAC

Way to calculate Host authentication cryptogram and CMAC will be illustrated by example below: 

8050000008659CFAB838A36C9E SW611C
00C000001CSW00000000000000000000FF02000092F744482D1E 26A365DF89B1EAEA9000
8482000010448126B770B27702D770D0A0001B05AASW9000


1. Generate Session Key 

Figure 2: Session Key generation diagram
*constant for C-MAC: '0101'
  constant for R-MAC: '0102'
  constant for S-ENC: '0182'
  constant for DEK: '0181'
*Sequence counter - get it from response of INITIALIZE UPDATE command. refer to Table 2.
*CBC encryption: Triple DES in CBC mode, ICV: 0000000000000000



base key used(Depends on your implementation.Not a fixed value): 
ENC: 30313233435363738393A3B3C3D3E3F
MAC: 404142434445464748494A4B4C4D4E4F
DEK: 505152535455565758595A5B5C5D5E5F


a. generate S-ENC: 
Derivation data: 01820000000000000000000000000000
S-ENC: 8D04904F18B948EEB78A1972B9527E71

b. generate S-MAC: 
Derivation data: 01010000000000000000000000000000
S-MAC: D1C28C601652A4770D67AD82D2D2E1C4

2. Calculate Host Authentication Cryptogram


a. Concatenated data: Sequence Counter+Card Challenge+Host Challenge
    Concatenated data: 000092F744482D1E659CFAB838A36C9E

b. Apply DES padding: 
    - Append an '80' to the right of the data block;
    - If resultant data block is a multiple of 8 bytes, no further padding is required;
    - Append binary zeroes to the right of the data block until the data block length is a multiple of 8 bytes.
    * If data is being padded with the intention of generating a MAC, the padding is discarded following the            DES operation. 
   Padding data: 000092F744482D1E659CFAB838A36C9E8000000000000000

c.  Generate authentication cryptogram by using signature method. 
    Signature method: Full Triple DES, more specified: Triple DES in CBC mode, ICV: 0000000000000000
    Since K = K', Algorithm 3 is downgrade to Algorithm 1. So it is TDES in CBC mode.
    After encrypt: B84449ADC4325C5BF9366187E977797D448126B770B27702
    Host cryptogram will be the last 8 bytes.
    Host cryptogram: 448126B770B27702
 *Way to calculate Card authentication cryptogram is same as above. The only different is the concatenated data. Concatenated data: Host Challenge+Sequence Counter+Card Challenge.

3. Calculate C-MAC

a. Organise your APDU command: 8482000010448126B770B27702
b. Padded data: 8482000010448126B770B27702800000
c. C-MAC generation use Single DES Plus Final Triple DES (so called Retail MAC). Refer to Figure 3 below:
Key 1: D1C28C601652A477
Key 2: 0D67AD82D2D2E1C4
Retail MAC diagram
   Calculated CMAC: D770D0A0001B05AA






Monday, 7 May 2012

java垃圾收集算法与内存泄露

from:  http://blog.sina.com.cn/s/blog_531424210100yz4b.html

1.垃圾收集算法的核心思想


 
  Java语言建立了垃圾收集机制,用以跟踪正在使用的对象和发现并回收不再使用(引用)的对象。该机制可以有效防范动态内存分配中可能发生的两个危险:因内存垃圾过多而引发的内存耗尽,以及不恰当的内存释放所造成的内存非法引用。
  垃圾收集算法的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用, 则为垃圾对象,可以回收其占据的空间,用于再分配。垃圾收集算法的选择和垃圾收集系统参数的合理调节直接影响着系统性能,因此需要开发人员做比较深入的了 解。

2.触发主GC(Garbage Collector)的条件

JVM进行次GC的频率很高,但因为这种GC占用时间极短,所以对系统产生的影响不大。更值得关注的是主GC的触发条件,因为它对系统影响很明显。总的来说,有两个条件会触发主GC:
  ①当应用程序空闲时,即没有应用线程在运行时,GC会被调用。因为GC在优先级最低的线程中进行,所以当应用忙时,GC线程就不会被调用,但以下条件除外。
  ②Java堆内存不足时,GC会被调用。当应用线程在运行,并在运行过程中创建新对象,若这时内存空间不足,JVM就会强制地调用GC线程,以便回收 内存用于新的分配。若GC一次之后仍不能满足内存分配的要求,JVM会再进行两次GC作进一步的尝试,若仍无法满足要求,则 JVM将报“out of memory”的错误,Java应用将停止。
  由于是否进行主GC由JVM根据系统环境决定,而系统环境在不断的变化当中,所以主GC的运行具有不确定性,无法预计它何时必然出现,但可以确定的是对一个长期运行的应用来说,其主GC是反复进行的。

3.减少GC开销的措施

根据上述GC的机制,程序的运行会直接影响系统环境的变化,从而影响GC的触发。若不针对GC的特点进行设计和编码,就会出现内存驻留等一系列负面影响。为了避免这些影响,基本的原则就是尽可能地减少垃圾和减少GC过程中的开销。具体措施包括以下几个方面:
  (1)不要显式调用System.gc()
  此函数建议JVM进行主GC,虽然只是建议而非一定,但很多情况下它会触发主GC,从而增加主GC的频率,也即增加了间歇性停顿的次数。
  (2)尽量减少临时对象的使用
  临时对象在跳出函数调用后,会成为垃圾,少用临时变量就相当于减少了垃圾的产生,从而延长了出现上述第二个触发条件出现的时间,减少了主GC的机会。
  (3)对象不用时最好显式置为Null
  一般而言,为Null的对象都会被作为垃圾处理,所以将不用的对象显式地设为Null,有利于GC收集器判定垃圾,从而提高了GC的效率。
  (4)尽量使用StringBuffer,而不用String来累加字符串(详见blog另一篇文章JAVA中String与StringBuffer)
  由于String是固定长的字符串对象,累加String对象时,并非在一个String对象中扩增,而是重新创建新的String对象,如 Str5=Str1+Str2+Str3+Str4,这条语句执行过程中会产生多个垃圾对象,因为对次作“+”操作时都必须创建新的String对象,但 这些过渡对象对系统来说是没有实际意义的,只会增加更多的垃圾。避免这种情况可以改用StringBuffer来累加字符串,因StringBuffer 是可变长的,它在原有基础上进行扩增,不会产生中间对象。
  (5)能用基本类型如Int,Long,就不用Integer,Long对象
  基本类型变量占用的内存资源比相应对象占用的少得多,如果没有必要,最好使用基本变量。
  (6)尽量少用静态对象变量
  静态变量属于全局变量,不会被GC回收,它们会一直占用内存。
  (7)分散对象创建或删除的时间
  集中在短时间内大量创建新对象,特别是大对象,会导致突然需要大量内存,JVM在面临这种情况时,只能进行主GC,以回收内存或整合内存碎片,从而增 加主GC的频率。集中删除对象,道理也是一样的。它使得突然出现了大量的垃圾对象,空闲空间必然减少,从而大大增加了下一次创建新对象时强制主GC的机 会。

4.gc与finalize方法

⑴gc方法请求垃圾回收
  使用System.gc()可以不管JVM使用的是哪一种垃圾回收的算法,都可以请求Java的垃圾回收。需要注意的是,调用System.gc() 也仅仅是一个请求。JVM接受这个消息后,并不是立即做垃圾回收,而只是对几个垃圾回收算法做了加权,使垃圾回收操作容易发生,或提早发生,或回收较多而 已。
  ⑵finalize方法透视垃圾收集器的运行
  在JVM垃圾收集器收集一个对象之前 ,一般要求程序调用适当的方法释放资源,但在没有明确释放资源的情况下,Java提供了缺省机制来终止化该对象释放资源,这个方法就是finalize()。它的原型为:
  protected void finalize() throws Throwable
  在finalize()方法返回之后,对象消失,垃圾收集开始执行。原型中的throws Throwable表示它可以抛出任何类型的异常。
  因此,当对象即将被销毁时,有时需要做一些善后工作。可以把这些操作写在finalize()方法里。
  java 代码
  protected void finalize()
  {
  // finalization code here
  }
  ⑶代码示例
  java 代码
  class Garbage{
  int index;
  static int count;
  Garbage() {
  count++;
  System.out.println("object "+count+" construct");
  setID(count);
  }
  void setID(int id) {
  index=id;
  }
  protected void finalize() //重写finalize方法
  {
  System.out.println("object "+index+" is reclaimed");
  }
  public static void main(String[] args)
  {
  new Garbage();
  new Garbage();
  new Garbage();
  new Garbage();
  System.gc(); //请求运行垃圾收集器
  }
  }

5.Java 内存泄漏

由于采用了垃圾回收机制,任何不可达对象(对象不再被引用)都可以由垃圾收集线程回收。因此通常说的Java 内存泄漏其实是指无意识的、非故意的对象引用,或者无意识的对象保持。无意识的对象引用是指代码的开发人员本来已经对对象使用完毕,却因为编码的错误而意 外地保存了对该对象的引用(这个引用的存在并不是编码人员的主观意愿),从而使得该对象一直无法被垃圾回收器回收掉,这种本来以为可以释放掉的却最终未能 被释放的空间可以认为是被“泄漏了”。
  考虑下面的程序,在ObjStack类中,使用push和pop方法来管理堆栈中的对象。两个方法中的索引(index)用于指示堆栈中下一个可用位 置。push方法存储对新对象的引用并增加索引值,而pop方法减小索引值并返回堆栈最上面的元素。在main方法中,创建了容量为64的栈,并64次调 用push方法向它添加对象,此时index的值为64,随后又32次调用pop方法,则index的值变为32,出栈意味着在堆栈中的空间应该被收集。 但事实上,pop方法只是减小了索引值,堆栈仍然保持着对那些对象的引用。故32个无用对象不会被GC回收,造成了内存渗漏。
  java 代码
  public class ObjStack {
  private Object[] stack;
  private int index;
  ObjStack(int indexcount) {
  stack = new Object[indexcount];
  index = 0;
  }
  public void push(Object obj) {
  stack[index] = obj;
  index++;
  }
  public Object pop() {
  index--;
  return stack[index];
  }
  }
  public class Pushpop {
  public static void main(String[] args) {
  int i = 0;
  Object tempobj;
  //new一个ObjStack对象,并调用有参构造函数。分配stack Obj数组的空间大小为64,可以存64个对象,从0开始存储
  ObjStack stack1 = new ObjStack(64);
  while (i < 64)
  {
  tempobj = new Object();//循环new Obj对象,把每次循环的对象一一存放在stack Obj数组中。
  stack1.push(tempobj);
  i++;
  System.out.println("第" + i + "次进栈" + "\t");
  }
  while (i > 32)
  {
  tempobj = stack1.pop();//这里造成了空间的浪费。
  //正确的pop方法可改成如下所指示,当引用被返回后,堆栈删除对他们的引用,因此垃圾收集器在以后可以回收他们。
  
  i--;
  System.out.println("第" + (64 - i) + "次出栈" + "\t");
  }
  }
  }

6.如何消除内存泄漏

虽然Java虚拟机(JVM)及其垃圾收集器(garbage collector,GC)负责管理大多数的内存任务,Java软件程序中还是有可能出现内存泄漏。实际上,这在大型项目中是一个常见的问题。避免内存泄 漏的第一步是要弄清楚它是如何发生的。本文介绍了编写Java代码的一些常见的内存泄漏陷阱,以及编写不泄漏代码的一些最佳实践。一旦发生了内存泄漏,要 指出造成泄漏的代码是非常困难的。因此本文还介绍了一种新工具,用来诊断泄漏并指出根本原因。该工具的开销非常小,因此可以使用它来寻找处于生产中的系统 的内存泄漏。
  垃圾收集器的作用
  虽然垃圾收集器处理了大多数内存管理问题,从而使编程人员的生活变得更轻松了,但是编程人员还是可能犯错而导致出现内存问题。简单地说,GC循环地跟 踪所有来自“根”对象(堆栈对象、静态对象、JNI句柄指向的对象,诸如此类)的引用,并将所有它所能到达的对象标记为活动的。程序只可以操纵这些对象; 其他的对象都被删除了。因为GC使程序不可能到达已被删除的对象,这么做就是安全的。
  虽然内存管理可以说是自动化的,但是这并不能使编程人员免受思考内存管理问题之苦。例如,分配(以及释放)内存总会有开销,虽然这种开销对编程人员来 说是不可见的。创建了太多对象的程序将会比完成同样的功能而创建的对象却比较少的程序更慢一些(在其他条件相同的情况下)。
  而且,与本文更为密切相关的是,如果忘记“释放”先前分配的内存,就可能造成内存泄漏。如果程序保留对永远不再使用的对象的引用,这些对象将会占用并 耗尽内存,这是因为自动化的垃圾收集器无法证明这些对象将不再使用。正如我们先前所说的,如果存在一个对对象的引用,对象就被定义为活动的,因此不能删 除。为了确保能回收对象占用的内存,编程人员必须确保该对象不能到达。这通常是通过将对象字段设置为null或者从集合(collection)中移除对 象而完成的。但是,注意,当局部变量不再使用时,没有必要将其显式地设置为null。对这些变量的引用将随着方法的退出而自动清除。
  概括地说,这就是内存托管语言中的内存泄漏产生的主要原因:保留下来却永远不再使用的对象引用。
  典型泄漏
  既然我们知道了在Java中确实有可能发生内存泄漏,就让我们来看一些典型的内存泄漏及其原因。
  全局集合
  在大的应用程序中有某种全局的数据储存库是很常见的,例如一个JNDI树或一个会话表。在这些情况下,必须注意管理储存库的大小。必须有某种机制从储存库中移除不再需要的数据。
  这可能有多种方法,但是最常见的一种是周期性运行的某种清除任务。该任务将验证储存库中的数据,并移除任何不再需要的数据。
  另一种管理储存库的方法是使用反向链接(referrer)计数。然后集合负责统计集合中每个入口的反向链接的数目。这要求反向链接告诉集合何时会退出入口。当反向链接数目为零时,该元素就可以从集合中移除了。
  缓存
  缓存是一种数据结构,用于快速查找已经执行的操作的结果。因此,如果一个操作执行起来很慢,对于常用的输入数据,就可以将操作的结果缓存,并在下次调用该操作时使用缓存的数据。
  缓存通常都是以动态方式实现的,其中新的结果是在执行时添加到缓存中的。典型的算法是:
  检查结果是否在缓存中,如果在,就返回结果。
  如果结果不在缓存中,就进行计算。
  将计算出来的结果添加到缓存中,以便以后对该操作的调用可以使用。
  该算法的问题(或者说是潜在的内存泄漏)出在最后一步。如果调用该操作时有相当多的不同输入,就将有相当多的结果存储在缓存中。很明显这不是正确的方法。
  为了预防这种具有潜在破坏性的设计,程序必须确保对于缓存所使用的内存容量有一个上限。因此,更好的算法是:
  检查结果是否在缓存中,如果在,就返回结果。
  如果结果不在缓存中,就进行计算。
  如果缓存所占的空间过大,就移除缓存最久的结果。
  将计算出来的结果添加到缓存中,以便以后对该操作的调用可以使用。
  通过始终移除缓存最久的结果,我们实际上进行了这样的假设:在将来,比起缓存最久的数据,最近输入的数据更有可能用到。这通常是一个不错的假设。
  新算法将确保缓存的容量处于预定义的内存范围之内。确切的范围可能很难计算,因为缓存中的对象在不断变化,而且它们的引用包罗万象。为缓存设置正确的大小是一项非常复杂的任务,需要将所使用的内存容量与检索数据的速度加以平衡。
  解决这个问题的另一种方法是使用java.lang.ref.SoftReference类跟踪缓存中的对象。这种方法保证这些引用能够被移除,如果虚拟机的内存用尽而需要更多堆的话。
  ClassLoader
  Java ClassLoader结构的使用为内存泄漏提供了许多可乘之机。正是该结构本身的复杂性使ClassLoader在内存泄漏方面存在如此多的问题。 ClassLoader的特别之处在于它不仅涉及“常规”的对象引用,还涉及元对象引用,比如:字段、方法和类。这意味着只要有对字段、方法、类或 ClassLoader的对象的引用,ClassLoader就会驻留在JVM中。因为ClassLoader本身可以关联许多类及其静态字段,所以就有 许多内存被泄漏了。
  确定泄漏的位置
  通常发生内存泄漏的第一个迹象是:在应用程序中出现了OutOfMemoryError。这通常发生在您最不愿意它发生的生产环境中,此时几乎不能进 行调试。有可能是因为测试环境运行应用程序的方式与生产系统不完全相同,因而导致泄漏只出现在生产中。在这种情况下,需要使用一些开销较低的工具来监控和 查找内存泄漏。还需要能够无需重启系统或修改代码就可以将这些工具连接到正在运行的系统上。可能最重要的是,当进行分析时,需要能够断开工具而保持系统不 受干扰。
  虽然OutOfMemoryError通常都是内存泄漏的信号,但是也有可能应用程序确实正在使用这么多的内存;对于后者,或者必须增加JVM可用的 堆的数量,或者对应用程序进行某种更改,使它使用较少的内存。但是,在许多情况下,OutOfMemoryError都是内存泄漏的信号。一种查明方法是 不间断地监控GC的活动,确定内存使用量是否随着时间增加。如果确实如此,就可能发生了内存泄漏。 (本信息来源于 国信拉点 http://www.fsailing.com)

Friday, 4 May 2012

Program to find Mother's day date



Question: Use java language to write a program that could generate Mother’s Day date of each year. (Mother’s day located on 2nd week of May each year .)


Solution & problem faced: 

 
It’s seems perfect huh?
So let’s run it and see whether it could work correctly.
 
 
Oh my god. It’s failed. My code throw an exception named NumberFormatException. This exception is throw when execute the  line below:
Int year = Integer.parseInt(new String(b).trim());

At first, I thought it was because of I handle the data type incorrectly. I had a long try and research about it, but still the problem exist. Why why why? Long time struggle on it and finally I found out this is due I got the wrong format for the text file encoding.

 Path: Right click your .java file in eclipse>Properties>Resources>Text file encoding 





Lesson 1: Do pay attention to Text file encoding properties.  Make sure you know what encoding you would like to use.


Learning Source:



Now I change it back to US-ASC-II .  Run my code again and see whether it could work correctly. 
 


It seems correct right? I got the output. But when you see into details, you will find out that the date show is incorrect. Mother’s Day located on April? How come? It should located on May. Here’s come the second problem.


I got no idea how the problem could exist. But I guess it is because of my default setting for time zone and locale. By try an error, I add the code below to my program:
calendar.setFirstDayOfWeek (Calendar.MONDAY);       



Haha…It’s work finally. This is the output I get:
 



Final Code: