2016-02-19 49 views
2

我想閱讀Java卡上的TLV編碼證書(恩智浦JCOP J3D081,JCOP版本2.4.2,Java卡版本3.0.1經典版)。讀取JavaCard Classic上的TLV編碼數據

帽文件創建成功,但是當我嘗試在卡上安裝它,我得到一個錯誤gpshell:

load() returns 0x80206A80 (6A80: Wrong data/Incorrect values in command data.)

我使用JCDK 3.0.3的罐子,這通常與東西就像橢圓曲線等等。TLV的東西有什麼不同?

使用的applet代碼(不使用BERTLV的東西時,安裝精細):

package org.thomas; 

import javacard.framework.APDU; 
import javacard.framework.Applet; 
import javacard.framework.ISO7816; 
import javacard.framework.ISOException; 
import javacard.framework.Util; 
import javacardx.framework.tlv.BERTLV; 
import javacardx.framework.tlv.ConstructedBERTLV; 

public class TlvApplet extends Applet { 

    private ConstructedBERTLV certificate; 
    byte[] certificateLength = new byte[2]; 

    /** 
    * TlvApplet constructor 
    * 
    * @constructor 
    */ 
    private TlvApplet() { 

     // Register with the JCRE 
     register(); 
    } 

    /** 
    * Installs 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 TlvApplet(); 
    } 

    public void process(APDU apdu) throws ISOException { 

     byte buffer[] = apdu.getBuffer(); 
     short incomingLength = apdu.setIncomingAndReceive(); 

     certificate = (ConstructedBERTLV) BERTLV.getInstance(buffer, 
      ISO7816.OFFSET_CDATA, incomingLength); 


     certificateLength[0] = (byte) (certificate.size() & 0xff); 
     certificateLength[1] = (byte) ((certificate.size() >> 8) & 0xff); 

     Util.arrayCopyNonAtomic(certificateLength, (short) 0, buffer, 
      ISO7816.OFFSET_CDATA, (short) 2); 

    } 

} 

我用下面的螞蟻的build.xml創建CAP文件:

<?xml version="1.0" encoding="UTF-8" ?> 
<project default="convert" name="Create JC 3 applet" basedir="."> 
<property environment="env" /> 

<!-- Include properties in the build.properties file --> 
<property file="build.properties" /> 

<!-- Build specific properties --> 
<property name="source.path" location="${basedir}/${source.folder}" /> 
<property name="jcdk.libs" location="${basedir}/${jcdk.basefolder}/${jcdk.subfolder.libs}" /> 
<property name="jcdk.apiexports" location="${basedir}/${jcdk.basefolder}/${jcdk.subfolder.apiexportfiles}" /> 
<property name="target.path.classes" 
location="${basedir}/${target.basefolder}/${target.subfolder.classes}" /> 
<property name="target.path.cap" 
location="${basedir}/${target.basefolder}/${target.subfolder.applet}" /> 

<!-- set the classpath for the tasks and the API, include all jar files --> 
<path id="classpath" description="Sets the classpath to Java Card API and tools"> 
    <fileset dir="${jcdk.libs}"> 
     <include name="*.jar" /> 
    </fileset> 
</path> 

<!-- set the export path to the Java Card export files --> 
<path id="export" description="set the export file path"> 
    <fileset dir="${jcdk.apiexports}"> 
     <include name="**/*.exp" /> 
    </fileset> 
    <pathelement path="${jcdk.apiexports}" /> 
    <pathelement path="${target.path.classes}" /> 
</path> 

<path id="capexport" description="set the export file for the cap path"> 
    <fileset dir="${jcdk.apiexports}"> 
     <include name="**/*.exp" /> 
    </fileset> 
    <pathelement path="${jcdk.apiexports}" /> 
</path> 

<!-- Definitions for tasks for Java Card tools --> 
<taskdef name="apdu" classname="com.sun.javacard.ant.tasks.APDUToolTask" classpathref="classpath" /> 
<taskdef name="capgen" classname="com.sun.javacard.ant.tasks.CapgenTask" classpathref="classpath" /> 
<taskdef name="convert" classname="com.sun.javacard.ant.tasks.ConverterTask" classpathref="classpath" /> 
<taskdef name="verifyexport" classname="com.sun.javacard.ant.tasks.VerifyExpTask" classpathref="classpath" /> 
<taskdef name="verifycap" classname="com.sun.javacard.ant.tasks.VerifyCapTask" classpathref="classpath" /> 
<taskdef name="verifyrevision" classname="com.sun.javacard.ant.tasks.VerifyRevTask" classpathref="classpath" /> 
<typedef name="appletnameaid" classname="com.sun.javacard.ant.types.AppletNameAID" classpathref="classpath" /> 
<typedef name="jcainputfile" classname="com.sun.javacard.ant.types.JCAInputFile" classpathref="classpath" /> 
<typedef name="scriptgen" classname="com.sun.javacard.ant.tasks.ScriptgenTask" classpathref="classpath" /> 

<target name="init"> 
    <mkdir dir="${target.path.classes}" /> 
</target> 

<target name="clean"> 
    <delete dir="${target.path.classes}" /> 
</target> 

<target name="compile" depends="init" description="Compile source code to class files"> 
    <javac debug="${javac.debug}" 
    optimize="${javac.optimize}" 
    srcdir="${source.path}" 
    destdir="${target.path.classes}" 
    source="${javac.version.source}" 
    target="${javac.version.target}"> 
    <classpath refid="classpath" /> 
    </javac> 
</target> 

<target name="convert" depends="compile" description="Convert class files to cap files"> 
    <convert packagename="${package.name}" 
    packageaid="${package.aid}" 
    majorminorversion="${applet.version}" 
    classdir="${target.path.classes}" 
    outputdirectory="${target.path.cap}" 
    jca="${cap.creation.jca}" 
    exp="${cap.creation.exp}" 
    cap="true" 
    debug="${cap.creation.debug}" verbose="${cap.creation.verbose}" 
    noverify="${cap.creation.noverify}"> 
    <appletnameaid aid="${applet.aid}" appletname="${applet.name}" /> 
    <exportpath refid="capexport" /> 
    <classpath refid="classpath" /> 
    </convert> 
</target> 

<target name="all" depends="clean, convert" /> 

</project> 

構建。使用的屬性:

# Source folder 
source.folder     = src/org/thomas 

# Java Card Development Kit folders 
jcdk.basefolder     = lib/javaCardKit303 
jcdk.subfolder.apiexportfiles = api_export_files 
jcdk.subfolder.libs    = lib 

# Target folders (will be created, no need to adapt) 
target.basefolder    = target 
target.subfolder.classes  = classes 
target.subfolder.applet   = applet 

# Applet properties 
package.aid  = 0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x42 
package.name = org.thomas 

applet.aid  = 0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x42:0x42 
applet.name  = TlvApplet 
applet.version = 1.0 

# Java class compiler options 
javac.debug    = no 
javac.optimize   = no 
javac.version.source = 1.5 
javac.version.target = 1.5 


# CAP file creation options 
cap.creation.verbose = false 
cap.creation.noverify = false 
cap.creation.debug  = false 
cap.creation.jca  = false 
cap.creation.exp  = false 

所以懷疑cap是用api_connected.jar編譯的,但是remo從套件中取出文件,沒有改變任何東西。

任何幫助,將不勝感激。在此先感謝,托馬斯

回答

2

該卡根本不支持java卡API的TLV類。 JC API只是一個建議,但卡製造商可能會選擇實施它的一個子集。

一般來說,javacardx中的任何內容都是可選的(因此末尾的x)。 javacard中的API方法必須實現。即使對於javacard包和類,並不是所有功能都可能在運行時可用。例如,密碼算法可能不存在。

+1

...你可以很容易地實現你自己的TLVReader/TLVWriter類。 – vojta

+0

@vojta取決於你想提供多少功能。對於TLV類,它有助於測試他們使用某種類型的JUnit測試... –

+0

一個很好的tlv解析器肯定是一個問題,對於java卡 –