跳到主要内容

数据采集

本章节使用nut_stm32_f103c8作为Nut(其出厂时已经包含Gloden固件供演示、测试使用),演示基础的数据采集流程的部署。使用Jupyter作为开发环境(使用pip install cracknuts[jupyter]进行安装)。

本章节内容会对必要的Jupyter基础操作进行描述,如果您对Jupyter比较熟悉可以跳过。需要了解更多有关Jupyter的内容可以访问Project Jupyter Documentation

创建Jupyter记事本

CrackNuts环境中执行命令cracknuts labjupyter lab打开Jupyter环境。

image-20241129093834443

提示

Jupyter默认安装情况下是英文,如果您需要中文环境可以执行pip install jupyterlab-language-pack-zh-CN命令安装中文语言包,并在启动Jupyter后在Settings -> Language中进行切换。

双击Jupyter启动页的笔记本-Python3(ipykernel)创建新笔记

image-20241129093914741

连接设备

在新建的笔记文件中,插入如下代码并执行(可以在选中该编辑框后点击上方的运行按钮执行或者Crtl + Enter快捷键执行)创建CrackerS1设备对象用以连接设备使用。

# 引入依赖
import cracknuts as cn

# 创建 cracker
cracker = cn.new_cracker('192.168.0.10')

image-20241205102039622

提示

192.168.0.10CrackerS1设备默认出厂IP地址,请根据您实际IP进行调整。

cn.new_cracker('192.168.0.10')默认创建的设备类型为S1。如果需要其他类型需要在参数中指定,如:cn.new_cracker('192.168.0.10', module = CrackerG1) 或者 cn.new_cracker('192.168.0.10', module = 'G1')

准备设备确保设备与上位机计算机能够通信,插入如下代码并执行进行设备连接,连接成功后代码会很快执行完成并无错误输出:

cracker.connect() # 连接设备

image-20241205102519618

如果设备连接不成功将出现如下错误日志:

image-20241205102638087

提示

如果设备与上位机计算机通过有线网卡直连,可配置上位机有线网卡IP地址为192.168.0.11/24,并通过ping命令确定与设备联通情况。

获取设备信息

创建一个单元格,执行如下代码可以获取设备ID信息:

cracker.get_id() # 获取设备ID

alt text

创建控制流程

控制流程指的是上位机采集数据的一个固定执行顺序,上位机中使用Acquisition类代表。以下代码是一段用于CrackerS1 - STM32 设备的AES能量轨迹采集代码,

import random
import time
from cracknuts.cracker import serial


cmd_set_aes_enc_key = "01 00 00 00 00 00 00 10"
cmd_aes_enc = "01 02 00 00 00 00 00 10"

aes_key = "11 22 33 44 55 66 77 88 99 00 aa bb cc dd ee ff"
aes_data_len = 16

sample_length = 1024 * 20

def init(c):
cracker.nut_voltage_enable()
cracker.nut_voltage(3.4)
cracker.nut_clock_enable()
cracker.nut_clock_freq('8M')
cracker.uart_enable()
cracker.osc_sample_clock('48m')
cracker.osc_sample_length(sample_length)
cracker.osc_trigger_source('N')
cracker.osc_analog_gain('B', 10)
cracker.osc_trigger_level(0)
cracker.osc_trigger_mode('E')
cracker.osc_trigger_edge('U')
cracker.uart_config(baudrate=serial.Baudrate.BAUDRATE_115200, bytesize=serial.Bytesize.EIGHTBITS, parity=serial.Parity.PARITY_NONE, stopbits=serial.Stopbits.STOPBITS_ONE)

time.sleep(2)
cmd = cmd_set_aes_enc_key + aes_key
status, ret = cracker.uart_transmit_receive(cmd, timeout=1000, rx_count=6)

def do(c):

plaintext_data = random.randbytes(aes_data_len)
tx_data = bytes.fromhex(cmd_aes_enc.replace(' ', '')) + plaintext_data
status, ret = cracker.uart_transmit_receive(tx_data, rx_count= 6 + aes_data_len, is_trigger=True)

return {
"plaintext": plaintext_data,
"ciphertext": ret[-aes_data_len:],
"key": bytes.fromhex(aes_key)
}


acq = cn.new_acquisition(cracker, do=do, init=init)

上面的代码中,定义了 initdo 两个方法,分别定义了初始化Cracker设备和向Cracker设备发送AES加密的数据两组操作。这组代码就实现了基础的AES加密能量数据的采集。

这里通过两个方法分别接收一个Cracker参数 ,供方法内部调用。

Cracker采集控制面板

插入如下代码并执行将显示Cracker采集控制面板界面,该界面集成Cracker设备控制、曲线采集流程控制、曲线监控于一体。

cn.panel(acq)

执行后展示效果如下:

alt text

能量曲线采集

Cracker采集控制面板界面,点击连接后界面将展示设备的ID、名称、版本信息,并且激活下方的配置面板和波形监控面板。

点击测试按钮,即可对设备进行实时调试(监控波形,需要打开监控开关),确保采集到正确的波形数据:

alt text

在调整到合适的参数后(在按照上述代码进行采集并使用NUT 103 golden 固件时,无需调整已是最好的效果),停止测试模式,点击运行按钮即可开始采集并保存波形数据:

alt text

至此,恭喜您,您已经成功使用CrackNuts采集到了能量轨迹波形数据。

提示

默认情况下随Cracker配套的 Nut(smt32_f103c8)已经烧录了HSI.elf固件,其他更多可用的固件可到https://pan.baidu.com/s/1PXyKqeTfemepZ-wD9gDwYQ?pwd=2cdaNutGolden 文件夹进行下载。

能量曲线使用

采集到的能量曲线数据存储格式默认位scarr格式,他是使用zarr格式作为存储基础,并且在CrackNuts增加了额外的数据,具体数据格式如下:

  • traces:
    • directory.zarr/X/Y/traces
  • metadata:
    • directory.zarr/X/Y/ciphertext
    • directory.zarr/X/Y/plaintext
    • (optional) directory.zarr/X/Y/key
    • (optional) directory.zarr/X/Y/extended

采集到的能量曲线数据默认存储在Jupyter notebook的同级目录的dataset目录下,以时间戳命名,可以使用如下方式加载已经保存到本地的曲线文件

  • 使用CrackNutsTraceDataSet:

    from cracknuts.trace import ScarrTraceDataset
    ds = ScarrTraceDataset.load(r'dataset\20250512163354.zarr')

    该方式打开的曲线可通过CrackNuts提供的曲线查看插件进行查看:

    import cracknuts as cn
    pt = cn.panel_trace()
    pt.set_trace_dataset(ds)
    pt

    alt text 通过以下代码,可以控制显示曲线的索引和区间:

    pt.show_trace[0, 10:20]  # 显示通道0的10到20(不包含)的曲线,该索引写法支持类似numpy复杂索引格式
    pt.change_range(400, 1000) # 显示400-1000这个区间
  • 直接使用zarr打开

    import zarr

    zd = zarr.open(r'D:\project\cracknuts\demo\jupyter\dataset\20250515165503.zarr')

    zd.tree()

    可以看到数据的格式如下:
    alt text