首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java卡小程序、安全数据传输和安全通道

Java卡小程序、安全数据传输和安全通道
EN

Stack Overflow用户
提问于 2015-04-05 09:02:17
回答 4查看 3.3K关注 0票数 6

我想用这样一种方式编写我的applet :它的APDU命令和状态词在我的卡和阅读器之间的传输通道中不清晰。我的意思是我不想发送APDU命令和响应为第三方的纯文本。

我想我有两个选择:

  1. 在卡上选择了我的applet之后,对于所有其他命令,在APDU命令的数据部分上执行加密功能,并在卡片上对它们进行解密,然后对它们进行分析。请注意,我不能使用此方法对整个命令进行加密,因为结果可能与另一个SELECT APDU命令发生冲突,而卡的SD错误地将其识别为SELECT命令。是那么回事吗?

其图表:

  1. 使用SD安全通道:据我所知,安全通道意味着:整体APDU命令、响应以加密形式发送(即它们在源中加密(安全域/卡片读取器),并在目的地(安全域/卡片读取器)解密。是那么回事吗?据我所知,SD在这个机制中扮演加密方法的角色,而我的applet和SD之间的通信是在普通的(下图)中,对吗?

其图表:

还有别的办法吗?

第一个解决方案似乎不够好,因为:

  1. 我必须亲自执行!:)
  2. 我们不能向第三方隐藏命令和响应的所有部分(我们只能隐藏数据)。

我说的对吗?

现在,假设我希望确保我的applet只适用于使用安全通道传输的APDU命令。我想我又有两个选择:

  1. 把卡片放在SECURED状态。由于用户无法在此状态下使用纯文本APDU命令与卡通信(对吗?)因此,他必须使用安全通道将命令发送给我的applet。对吗?如果不正确,是否有办法强迫SD只与安全通道一起工作?
  2. 将卡保存在任何生命周期(例如OP_READY),但是在接收任何APDU命令时,请检查CLA部分,看看它是否是安全传输的!(有可能吗?来自安全通道的APDU命令的CLA部分与其他部分有什么区别吗?我说得对吗?

还有别的办法吗?

最后,主要问题是:

如何使用SD与我的applet进行安全的通信?因为我认为我必须使用GlobalPlatform类(是吗?),我看了一下它的API-s。我在一个名为getSecureChannel的包中找到了一个名为org.globalplatform.GPSystem的方法。我做得对吗?我必须用这个方法吗?

我知道这可能太长,无法回答,但我相信,它不仅澄清了许多问题,不仅对我,也对其他未来的观众。

我很感谢有人为我在这个问题上提供了任何帮助。

而一个小程序样本则更有价值。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-04-16 10:34:14

我会按顺序回答:

  1. 是的,对于ISO/IEC 7816-4,只有数据部分是加密的.标头只受身份验证标记的保护。
  2. 不,Global安全通道也只是(可选)加密数据。但是,完整性超过了头数据和命令数据。
  3. 不,安全状态只适用于,您必须使用为自己编程。GP API具有执行身份验证、请求安全通道和检索当前状态的访问方法。
  4. 正确,CLA字节决定APDU是否被加密(而不是加密的方式)。如果CLA的第一个比特为零,那么您的安全通道必须符合ISO/IEC 7816-4。
票数 3
EN

Stack Overflow用户

发布于 2015-06-15 07:17:57

不要担心通过applet进行安全的信道通信。如果在applet中使用,这是非常简单的。

您不需要考虑很多问题,只要尝试编写一个安全通道applet,它就会按照命令数据中定义的安全级别来处理applet。

参考GP安全通道APIs:http://www.win.tue.nl/pinpasjc/docs/apis/gp22/

你应该把卡保持在安全状态。

这是用于安全通道scp02的示例applet:

代码语言:javascript
复制
package secureChannel;

import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;

import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;

public class Scp02 extends Applet
{
    final static byte INIT_UPDATE       = (byte) 0x50;

    final static byte EXT_AUTHENTICATE  = (byte) 0x82;

    final static byte STORE_DATA        = (byte) 0xE2;

    public static void install(byte[] bArray, short sOffset, byte bLength)
    {
        new Scp02().register(bArray, sOffset, bLength);
    }

    public void process(APDU apdu) throws ISOException
    { 
        SecureChannel sc = GPSystem.getSecureChannel();

        byte[] buffer = apdu.getBuffer();

        short inlength = 0;

        switch (ISO7816.OFFSET_INS)
        {
            case INIT_UPDATE:
            case EXT_AUTHENTICATE:
                inlength = apdu.setIncomingAndReceive();
                sc.processSecurity(apdu);
            break;

            case STORE_DATA:
                //Receive command data
                inlength = apdu.setIncomingAndReceive();
                inlength = sc.unwrap(buffer, (short) 0, inlength);

                apdu.setOutgoingAndSend((short)0, inlength);

                //Process data
                break;
        }
    }
}
票数 4
EN

Stack Overflow用户

发布于 2019-01-04 11:21:58

出于Google搜索的考虑,Anurag Bajpai的代码不能工作而不做任何修改,因为正如GP安全通道API中所述,applet应该输出最终的响应数据:

如果存在响应数据,则该数据将放在偏移量ISO7816.OFFSET_CDATA处的APDU缓冲区中。返回值表示长度,如果有必要,applet负责输出这些数据。

因此,修正后的代码是:

代码语言:javascript
复制
package secureChannel;

import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;


public class Scp02 extends Applet
{
    final static byte INIT_UPDATE       = (byte) 0x50;

    final static byte EXT_AUTHENTICATE  = (byte) 0x82;

    final static byte STORE_DATA        = (byte) 0xE2;

    public static void install(byte[] bArray, short sOffset, byte bLength)
    {
        new Scp02().register(bArray, sOffset, bLength);
    }

    public void process(APDU apdu) throws ISOException
    { 
        SecureChannel sc = GPSystem.getSecureChannel();

        byte[] buffer = apdu.getBuffer();

        short inlength = 0;

        switch (ISO7816.OFFSET_INS)
        {
            case INIT_UPDATE:
            case EXT_AUTHENTICATE:
                inlength = apdu.setIncomingAndReceive();
                short respLen = sc.processSecurity(apdu);
                apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, respLen);
            break;

            case STORE_DATA:
                //Receive command data
                inlength = apdu.setIncomingAndReceive();
                inlength = sc.unwrap(buffer, (short) 0, inlength);

                apdu.setOutgoingAndSend((short)0, inlength);

                //Process data
            break;
    }
}

}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29455715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档