数据采集
本章节使用nut_stm32_f103c8
作为Nut(其出厂时已经包含Gloden固件供演示、测试使用),演示基础的数据采集流程的部署。使用Jupyter
作为开发环境(使用pip install cracknuts[jupyter]
进行安装)。
本章节内容会对必要的Jupyter
基础操作进行描述,如果您对Jupyter
比较 熟悉可以跳过。需要了解更多有关Jupyter
的内容可以访问Project Jupyter Documentation 。
创建Jupyter记事本
在CrackNuts
环境中执行命令cracknuts lab
或 jupyter lab
打开Jupyter
环境。
Jupyter
默认安装情况下是英文,如果您需要中文环境可以执行pip install jupyterlab-language-pack-zh-CN
命令安装中文语言包,并在启动Jupyter
后在Settings -> Language
中进行切换。
双击Jupyter
启动页的笔记本
-Python3(ipykernel)
创建新笔记
连接设备
在新建的笔记文件中,插入如下代码并执行(可以在选中该编辑框后点击上方的运行按钮执行或者Crtl + Enter
快捷键执行)创建CrackerS1
设备对象用以连接设备使用。
# 引入依赖
import cracknuts as cn
# 创建 cracker
cracker = cn.new_cracker('192.168.0.10')
192.168.0.10
为CrackerS1
设备默认出厂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() # 连接设备
如果设备连接不成功将出现如下错误日志:
如果设备与上位机计算机通过有线网卡直连,可配置上位机有线网卡IP地址为192.168.0.11/24
,并通过ping
命令确定与设备联通情况。
获取设备信息
创建一个单元格,执行如下代码可以获取设备ID信息:
cracker.get_id() # 获取设备ID
创建控制流程
控制流程指的是上位机采集数据的一个固定执行顺序,上位机中使用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)
上面的代码中,定义了 init
和 do
两个方法,分别定义了初始化Cracker
设备和向Cracker
设备发送AES
加密的数据两组操作。这组代码就实现了基础的AES
加密能量数据的采集。
这里通过两个方法分别接收一个Cracker
参数 ,供方法内部调用。
Cracker采集控制面板
插入如下代码并执行将显示Cracker采集控制面板界面,该界面集成Cracker
设备控制、曲线采集流程控制、曲线监控于一体。
cn.panel(acq)
执行后展示效果如下:
能量曲线采集
在Cracker采集控制面板界面,点击连接后界面将展示设备的ID、名称、版本信息,并且激活下方的配置面板和波形监控面板。
点击测试按钮,即可对设备进行实时调试(监控波形,需要打开监控开关),确保采集到正确的波形数据:
在调整到合适的参数后(在按照上述代码进行采集并使用NUT 103 golden 固件时,无需调整已是最好的效果),停止测试模式,点击运行按钮即可开始采集并保存波形数据:
至此,恭喜您,您已经成功使用CrackNuts
采集到了能量轨迹波形数据。
默认情况下随Cracker
配套的 Nut(smt32_f103c8)
已经烧录了HSI.elf
固件,其他更多可用的固件可到https://pan.baidu.com/s/1PXyKqeTfemepZ-wD9gDwYQ?pwd=2cda的 NutGolden
文件夹进行下载。
能量曲线使用
采集到的能量曲线数据存储格式默认位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目录下,以时间戳命名,可以使用如下方式加载已经保存到本地的曲线文件
-
使用
CrackNuts
的TraceDataSet
: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通过以下代码,可以控制显示曲线的索引和区间:
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()可以看到数据的格式如下: