打造区块链应用的安全性:第 2 部分 – 使用交钥匙型解决方案进行快速部署
投稿人:DigiKey 北美编辑
2019-10-15
编者按:区块链技术及其交易方法的细节非常复杂。本系列文章包括两部分,第 1 部分概述了区块链结构及其交易过程。这提供了一个背景,帮助您了解为什么说保护私钥是区块链安全的核心所在,进而介绍一个用于保护私钥的交钥匙型解决方案。本文,即第 2 部分,将向开发人员展示如何使用这一基于硬件的交钥匙型解决方案更轻松地保护区块链交易。
除了其在加密货币中的常见用途外,区块链技术还可以为开发人员提供具有广泛适用性的安全基础架构。它的去中心化架构消除了对中央管理机构的需求,转而依靠私钥和加密方法来保护资产及其在各方之间的交换。因此,区块链系统的安全性关键取决于密钥的安全性以及它们在稳健算法中的正确使用。
尽管有现成的合适算法,但是实现需要大量的专业知识和经验,这样才能开发出安全的解决方案并将其整合到目标应用中。如果没有合适的工具将区块链构建到应用的核心中,开发人员就会发现他们的工作停滞不前,甚至容易受到网络窃贼的攻击。
本文向开发人员展示如何使用 Infineon Technologies 提供的基于硬件的交钥匙型区块链安全解决方案,以更轻松地方式保护区块链交易。
私钥安全性
区块链消除了要有中央管理机构批准交易的需要。取而代之的是,这项技术依靠共识机制来维持区块链的完整性,而区块链则通过使用加密方法和私钥/公钥对进行签名和验证的一组交易来持续扩展。实际上,私钥在区块链系统中充当所有权凭据。因意外或盗窃而造成的私钥丢失或暴露已经造成了重大的加密货币损失。因此,私钥的安全性是部署区块链应用时最重要的问题。
早期基于软件或有限硬件安全性的方法可能会使私钥容易受到各种攻击。相比之下,更强大的解决方案构建于可针对各种直接和间接威胁提供深度保护的安全控制器之上。Infineon Blockchain Security 2Go 入门套件 (BLOCKCHAINSTARTKITTOBO1) 使用基于此类安全控制器的解决方案,提供了区块链安全所需的深度保护。
开发人员无需再面对实现自有解决方案的挑战,而是可以为用户提供内置区块链安全机制支持的非接触式智能卡,包括支持交易签名,这是扩展区块链的关键第一步(图 1)。
图 1:Infineon Blockchain Security 2Go 智能卡通过对区块链机制(包括用于扩展区块链的签名交易)的内置支持,简化了区块链安全的部署。(图片来源:Infineon Technologies)
安全平台
Infineon Blockchain Security 2Go 入门套件为区块链系统集成商提供了一个交钥匙型的安全解决方案,且不需要获取安全设备通常所需的保密协议。
该套件旨在使用 Infineon 提供的开源软件进行快速部署,包括五张智能卡,可实现包括生成安全密钥、创建签名和 PIN 身份验证在内的关键区块链机制。此外,开发人员还可从相关的 Infineon Security 2Go 10 卡包 (BLOCKCHAIN10CARDSTOBO1) 获得智能卡。
这些卡在某些地区符合用于常规支付卡和身份证的 ISO/IEC 7810 ID-1 标准。关于连接性,这些智能卡集成了一根基于 ISO/IEC 14443 标准的 1 类天线,适用于使用近场通信 (NFC) 的非接触式卡。
嵌入每张卡中的安全控制器提供了基于硬件的安全性,用于创建和存储多达 255 个私钥/公钥对以及执行加密算法。除了集成真随机数发生器 (TRNG),这些卡片还支持两种算法:一种是使用 256 位高级加密标准 (AES) 的对称加密算法;另一种是使用 256 位椭圆曲线加密 (ECC) 并预载了 secp256k1 ECC 曲线(通常用于包括比特币和以太坊在内的加密货币)的非对称加密算法。
凭借对区块链安全机制的专门支持,这些卡为保护区块链交易提供了即时解决方案。区块链系统集成商无需花费时间来构建安全的签名方法,而只需将智能卡交给用户,让其在与已部署的区块链系统进行交互时使用。
交互更简单
对于用户而言,智能卡提供了一种简单的方法,在其私钥受到充分保护的情况下执行区块链交易。这些卡旨在与接口设备(例如 NFC 智能手机或配备独立 NFC 智能卡读取器的计算机)上运行的软件搭配使用。在运行区块链应用时,用户通过将卡放置在接口设备上来激活卡的功能(图 2)。
图 2:如下所示,用户可以通过将智能卡靠近 NFC 读取器天线(例如 Google Pixel 智能手机背面的光泽区域)来调用智能卡的功能。(图片来源:Infineon Technologies)
为了即时评估 Security 2Go 智能卡,Infineon 提供了一个 Android 移动应用,以演示其在典型场景下的使用。该移动应用在支持 NFC 的智能手机上启动后,会提示用户将智能卡贴放在智能手机的 NFC 天线区域,从而启用完整的移动应用界面(图 3)。
图 3:由 Coinfinity GmbH 为 Blockchain Security 2Go 入门套件开发的一款预置 Android 应用。这款应用显示了在卡请求与智能卡(左)建立联系后,如何使用智能卡功能来演示不同的使用场景(右)。(图片来源:Infineon Technologies)
在此移动应用和其他部署的幕后,智能手机或其他接口设备上运行的软件会发出命令来执行各种功能,例如生成新的密钥对或获取有关现有密钥对的信息。在这些命令和其他命令序列的整个执行过程中,私钥永远不会离开智能卡。在响应涉及私钥的命令时,智能卡最多将一个密钥句柄返回至接口设备。接口设备软件进而使用该句柄来执行相关的命令,例如检索与特定私钥配对的公钥(图 4)。
通过这种方法,在接口上运行的软件可以在不损害私密数据的情况下,完成与区块链系统交互所需的全部操作。
图 4:智能手机或智能卡读取器等接口设备会向 Infineon Blockchain Security 2Go 智能卡发出诸如此密钥生成请求之类的命令,而智能卡则会创建私钥/公钥对并返回公钥而不泄露私钥。(图片来源:Infineon Technologies)
接口设备软件保留执行应用特定功能的责任,例如将公钥转换为用于每个交易的(通常是唯一的)区块链地址。例如,比特币地址使用公钥作为单向哈希算法的输入,该算法会生成一个依赖于公钥但不能用于重新创建公钥的地址。
类似地,为了对交易请求进行签名,接口会向智能卡发出一条命令和随附的哈希结果。作为响应,智能卡将签名返回给接口设备(图 5)。
图 5:对交易进行签名需要使用私钥,但是利用 Infineon Blockchain Security 2Go 智能卡,接口设备可以在不暴露最要紧的私钥的情况下接收签名。(图片来源:Infineon)
应用协议数据单元
对于每个命令和响应,接口设备和智能卡之间使用 ISO/IEC 7816 标准第 4 部分中定义的应用协议数据单元 (APDU) 进行交互。对于与智能卡的每次交互,接口设备均以 ISO/IEC-7816 标准命令 APDU 格式发出服务请求,并以标准响应 APDU 格式接收(可选的)响应(图 6)。
图 6:ISO/IEC 7816 标准命令 APDU 和响应 APDU 格式构成了接口设备与相容智能卡(例如 Infineon Blockchain Security 2Go 智能卡)之间的通信基础。(图片来源:Infineon Technologies)
在命令 APDU 中,智能卡提供商根据目标应用领域中使用的行业标准定义受支持的指令和参数。Infineon 为其 Blockchain Security 2Go 智能卡定义了一组利用智能卡功能所需的核心命令(表 1)。
表 1:Infineon Blockchain Security 2Go 智能卡的命令集。(表来源:由 DigiKey 根据 Infineon Technologies 提供的数据创建)
例如,要启动新会话,接口设备软件将使用 Infineon 为 Blockchain Security 2Go 入门套件提供的固定应用标识符 (AID) 的数据值来构建 SELECT APPLICATION 命令 APDU。在收到该命令 APDU 后,智能卡将针对新会话进行自身初始化,并发送相应的响应 APDU,其中包括一些智能卡元数据(图 7)。
图 7:Infineon 为其 Blockchain Security 2Go 智能卡提供了命令所需的以及在响应和错误代码中预期出现的特定 APDU 字段值,例如这组用于初始化智能卡的字段值,其中包括由 Infineon 提供的固定应用标识符 (AID)。(图片来源:Infineon Technologies)
定制软件
使用 Blockchain Security 2Go 智能卡创建新应用时,开发人员无需在此底层工作。Infineon 在其 Blockchain Security 2Go GitHub 知识库中提供了有关智能卡使用的样例应用和文档。
Infineon 在其 BlockchainSecurity2Go Android 代码 GitHub 知识库中包含了用于其 Android 移动应用的完整 Java 源代码。通过研究该代码库,软件程序员可以快速学习关键设计模式,包括初始化智能卡会话 (selectApplication()
),从智能卡读取公钥 (readPublicKeyFromCard()
),以及在卡上尚不存在公钥的情况下新建密钥对 (generateNewSecp256K1Keypair()
)(清单 1)。
副本 /** * Read public key from card, or create a new one if it doesn't exist yet.* * @param card nfc card * @return public key as hexadecimal String * @throws IOException on communication errors * @throws NfcCardException when card returns something other than 0x9000 or 0x61XX */ public static GetKeyInfoResponseApdu readPublicKeyOrCreateIfNotExists(NfcTranceiver card, int keyIndex) throws IOException, NfcCardException { try { selectApplication(card); // try to read public key return readPublicKeyFromCard(card, keyIndex); } catch (NfcCardException e) { // if Public key is not available yet (Status words: 0x6A88) if (e.getSw1Sw2() == SW_KEY_WITH_IDX_NOT_AVAILABLE) { int newKeyIndex; do { // create a new keypair newKeyIndex = generateNewSecp256K1Keypair(card); } while (newKeyIndex <= keyIndex); // and ask for the pubkey of the newly created keypair return readPublicKeyFromCard(card, newKeyIndex); } else { // throw all other exceptions to our caller throw e; } } }
清单 1:Infineon 提供了用于其 Blockchain Security 2Go Android 应用的完整源代码,展示了读取公钥和新建私钥/公钥对等基本交互。(代码来源:Infineon Technologies)
在该 Java 代码库中的实用程序类实现了详细交互,例如创建 SELECT APPLICATION APDU。调用清单 2(如下)中所示成员函数的例程会传递一个 aid
参数,其中保存了 Infineon Blockchain Security 2Go AID,该参数在数据包中前面的声明如下:
副本 public static final byte[] AID_INFINEON_BLOCKCHAIN2GO = fromHexString("D2760000041502000100000001"); public class SelectApplicationApdu extends BaseCommandApdu { /** * Instruction byte for SELECT APPLICATION operation.*/ private static final int INS_SELECT_APPLICATION = 0xA4; /** * Constructs a SELECT APPLICATION command apdu.*/ public SelectApplicationApdu(byte[] aid) { this.ins = INS_SELECT_APPLICATION; this.p1 = 0x04; this.setData(aid); this.leIncluded = true; } }
清单 2:Infineon Blockchain Security 2Go Android 应用源代码展示了如何创建用于初始化智能卡的命令 APDU。(代码来源:Infineon Technologies)
为了快速开发,Infineon 还提供了一个 Blockchain Security 2Go Python 库和基于该库构建的命令行界面。与 Java 版本一样,Python 代码演示了执行智能卡操作(如生成密钥对)所需的简单设计模式(清单 3)。
副本
def select_app(reader):
""" Sends command to select the Blockchain Security2GO application
Needs to be called after reset to allow for access to
blockchain commands.
Returns:
:obj:`tuple`: (pin_active, card_id, version).
pin_active:
bool: True if PIN is set on the card
card_id:
bytes: 10 byte unique card identifier
version:
str: card firmware version, following
semantic versioning.
Raises:
CardError: If card indicates a failure.
Any exceptions thrown by the reader wrapper are passed through. """
logger.debug('SELECT Blockchain Security 2Go starter kit')
aid = bytes.fromhex('D2760000041502000100000001')
r = reader.transceive(b'\x00\xA4\x04\x00', aid).check()
pin_active = True if r.resp[0] == 1 else False
card_id = r.resp[1:11]
version = r.resp[11:].decode('ASCII')
return (pin_active, card_id, version)
def generate_keypair(reader):
""" Sends command to generate new keypair
A new keypair is generated and stored.The ID identifying this
keypair is returned.A key using the `secp256k1`_ curve is generated.
Args:
reader (:obj:): object providing reader communication
Returns:
int: ID of the just generated keypair, to be used e.g. for
future signatures using ``generate_signature``
Raises:
CardError: If card indicates a failure, e.g. if card is full.
Any exceptions thrown by the reader wrapper are passed through.
.._secp256k1:
http://www.secg.org/sec2-v2.pdf
"""
logger.debug('GENERATE KEYPAIR')
r = reader.transceive(b'\x00\x02\x00\x00').check()
key_id = int(r.resp[0])
logger.debug('generated key %d', key_id)
return key_id
清单 3:Infineon Blockchain Security 2Go Python 库和随附的命令行界面通过全套服务例程协助进行快速开发,例如用于初始化 Blockchain Security 2Go 智能卡的 select_app()
函数,以及 generate_keypair()
),每个例程都演示了基本的智能卡交互设计模式。(代码来源:Infineon Technologies)
Blockchain Security 2Go Python 库采用典型的 Python 风格,基于现成的第三方模块构建而成。特别的是,Infineon 库使用了流行的 pyscard 模块,将其函数包装在自己的类定义中。例如,Blockchain Security 2Go Python 库通过查找个人电脑/智能卡 (PC/SC) 读取器开始智能卡会话。对于 Blockchain Security 2Go Python 库的主要 blocksec2go
模块,此发现使用函数 open_psycard()
进行,该函数是库类中包装 pyscard 函数的成员函数(清单 4)。
副本
class PySCardReader:
""" Wrapper to use PyScard with blocksec2go
Abstracts communication into a simple function
"""
def __init__(self, connection):
self.connection = connection
self.connection.connect()
def transceive(self, header, data = b'', le = -1):
apdu = Apdu(header, data, le)
logger.debug(apdu)
resp = self._transceive(bytes(apdu))
logger.debug(resp)
return resp
def _transceive(self, data):
resp, sw1, sw2 = self.connection.transmit(array.array('b', data).tolist())
return ApduResponse(array.array('B', resp).tobytes(), (sw1 << 8) + sw2)
清单 4:Infineon Blockchain Security 2Go Python 库使用其成员函数调用 pyscard 函数,来包装与此类中的第三方 pyscard 模块的交互。(代码来源:Infineon Technologies)
总结
区块链技术提供了一个框架,在不损害信息完整性或真实性的情况下扩展了信息的可访问性。区块链系统不依赖于中央管理机构,而是使用加密方法来验证交易并保护交易不被修改。对于这种方法至关重要的是,私钥需要有强大的安全机制,以防止对用户交易失去控制和区块链系统受到破坏。
如图所示,Infineon Blockchain Security 2Go 入门套件及其随附的开源软件为区块链系统集成商提供了一种即时安全的解决方案,并为用户提供了一种更简单、更安全的方法执行区块链交易。
免责声明:各个作者和/或论坛参与者在本网站发表的观点、看法和意见不代表 DigiKey 的观点、看法和意见,也不代表 DigiKey 官方政策。