安卓通过DIRECT IO和加密TF卡通信

安卓通过DIRECT IO和加密TF卡通信

问题背景

项目中在开发加密T卡,加密T卡和上位机通信的方式是在T卡上虚拟出文件,然后上位机通过读写该文件和加密T卡进行通信,在安卓手机上使用加密T卡的时候,出现一个问题,通过安卓的java层文件流的方式打开加密T卡中的文件,然后读出的数据都是0,和加密T卡根本通信不起来。

问题分析

1首先在windows上正常openfile ,然后readfile可以正常读取加密T卡发过来的数据。
2 使用linux系统,和安卓问题一致,可能安卓底层就是linux原因。
3 linux在内核层会有文件系统的缓冲,也就是使用read和write操作文件的时候,不会立马从磁盘写入和读出,而是内存中的缓冲,所以需要用到direct IO,直接和磁盘通信。

解决方式

1 安卓层采用JNI的方式来操作加密T卡中的文件
JNI 接口:

extern "C"
JNIEXPORT jboolean JNICALL Java_com_csizg_tfwrtest_libwrtest_SKFNative_readFile
        (JNIEnv *env, jclass jObj, jstring jfilePath, jint jreadBlockSize, jbyteArray joutData, jint joutDataLen) {
    int ret = -1;
    const char *filePath = NULL;
    UINT readBlockSize, outDataLen;
    BYTE *outData;
    
    if (jfilePath != NULL) {
        filePath = (env)->GetStringUTFChars(jfilePath, FALSE);
    } else {
        return FALSE;
    }
    readBlockSize = jIntToUINT(jreadBlockSize);
    outDataLen = jIntToUINT(joutDataLen);
    if (joutData != NULL) {
        outData = (BYTE *) (env)->GetPrimitiveArrayCritical(joutData, NULL);
        if (outData == NULL) {
            return FALSE;
        }
    }

    ret = tf_read(filePath, outData, outDataLen);

    if (ret < 0) {
        return FALSE;
    }

    (env)->ReleasePrimitiveArrayCritical(joutData, outData, JNI_ABORT);

    return TRUE;
}

2 在open文件的时候,指定O_DIRECT标志。

    fd1 = open(path_w, O_WRONLY | O_CREAT | O_NOCTTY | O_DIRECT);
    if (fd1 < 0) {
        LOGC_ERROR("dev1 open:");
        fd1 = -1;
        return -1;
    }

3 因为direct IO的特点,需要用户层的缓冲buff的地址以及大小都要和存储块大小对齐。具体原因讲解可以参考如下博文:
https://blog.csdn.net/yang15225094594/article/details/43268133

buff对齐源码:

    struct stat fstat_w;
    stat(path_w, &fstat_w);
    int blksize_w = (int) fstat_w.st_blksize;
    int align_w = blksize_w - 1;

    const char *buff_w = (char *) malloc((int) blksize_w + align_w);
    send_data_buffer = (char *) (((unsigned long int) buff_w + align_w) & ~((unsigned long int) align_w));

4 如果用户缓冲buff和存储块不对齐,read和write的时候,会报地址错误的error。

5 安卓JNI和direct IO 完整源码如下:
https://download.csdn.net/download/qq_39952971/18197909

测试结果

安卓手机通过JNI的方式open、read、write 加密T卡中的通信文件,可以实现利用加密T卡进行SM4加密流程,加密后的数据和其它SM4工具对比,结果一致。

plain data 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
enc data
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
ad c1 4 5a 98 9 9 3f fc 9 d6 c5 f5 ce e3 81 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

viqjeee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值