65.9K
CodeProject 正在变化。 阅读更多。
Home

示例代码:数据加密应用程序

2014年6月2日

CPOL

4分钟阅读

viewsIcon

21448

本文介绍了通过 Java* 或 OpenSSL* 可用的数据加密 API。 两种解决方案都适用于 Android* 操作系统。

引言

加密 很重要,因为它允许您安全地保护您不希望其他人访问的数据。加密已成为安全社区中的热门话题。 随着越来越多的移动设备存储着比以往任何时候都更有价值的信息,加密对于确保信息安全至关重要。

本文介绍了通过 Java* 或 OpenSSL* 可用的数据加密 API。 两种解决方案都适用于 Android* 操作系统。

我们建议您在阅读本文时尝试这些功能并编译代码。

数据加密代码和说明

如果您想在 Android 上加密数据,您有两个选择:Java Crypto API 和 OpenSSL API。 我们将向您展示如何使用这两种方法加密数据。

Java Crypto API

在 Android 上使用 Java Crypto API 非常简单。 首先,您需要为加密生成一个密钥。 javax.crypto 包中有一个 KeyGenerator 类可以为您完成这项工作。

    mKey = null;
    try {
        kgen = KeyGenerator.getInstance("AES");
        mKey = kgen.generateKey();

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

然后,您可以使用生成的密钥来加密数据文件。 这可以通过将字节块馈送到由 javax.crypto 创建的 AES Cipher 来完成。

// open stream to read origFilepath. We are going to save encrypted contents to outfile
    InputStream fis = new FileInputStream(origFilepath);        
    File outfile = new File(encFilepath);
    int read = 0;
    if (!outfile.exists())
        outfile.createNewFile();
        
    FileOutputStream encfos = new FileOutputStream(outfile);
    // Create Cipher using "AES" provider
    Cipher encipher = Cipher.getInstance("AES");
    encipher.init(Cipher.ENCRYPT_MODE, mKey);
    CipherOutputStream cos = new CipherOutputStream(encfos, encipher);
        
    // capture time it takes to encrypt file
    start = System.nanoTime();
    Log.d(TAG, String.valueOf(start));
        
    byte[] block = new byte[mBlocksize];
        
    while ((read = fis.read(block,0,mBlocksize)) != -1) {
        cos.write(block,0, read);
    }
    cos.close();
    stop = System.nanoTime();
        
    Log.d(TAG, String.valueOf(stop));
    seconds = (stop - start) / 1000000;// for milliseconds
    Log.d(TAG, String.valueOf(seconds));
        
    fis.close();

OpenSSL API

在 Android 上使用 OpenSSL 加密数据需要编写可以通过 JNI 调用在 Java 中访问的本地 C 代码。 这需要更多的工作,但您将获得更好的性能回报。

首先,让我们生成密钥和 iv。

unsigned char cKeyBuffer[KEYSIZE/sizeof(unsigned char)];
unsigned char iv[] = "01234567890123456";
int opensslIsSeeded = 0;
if (!opensslIsSeeded) {
    if (!RAND_load_file("/dev/urandom", seedbytes)) {
        return -1;
    }
    opensslIsSeeded = 1;
}

if (!RAND_bytes((unsigned char *)cKeyBuffer, KEYSIZE )) {
}

然后,我们可以使用生成的密钥 (cKeyBuffer) 来加密文件。 通过向其提供密钥和 iv 来初始化 EVP。 然后将字节块馈送到 EVP_EncryptUpdate 函数。 来自文件的最后一个字节块将需要馈送到 EVP_EncryptFinal_ex 函数。

if (!(EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, cKeyBuffer, iv ))) {
    ret = -1;
    printf( "ERROR: EVP_ENCRYPTINIT_EXn");
}
    
// go through file, and encrypt
if ( orig_file != NULL ) {
       origData = new unsigned char[aes_blocksize];
        encData = new unsigned char[aes_blocksize+EVP_CIPHER_CTX_block_size(e_ctx)]; // potential for encryption to be 16 bytes longer than original

    printf( "Encoding file: %sn", filename);

    bytesread = fread(origData, 1, aes_blocksize, orig_file);
    // read bytes from file, then send to cipher
    while ( bytesread ) {


        if (!(EVP_EncryptUpdate(e_ctx, encData, &len, origData, bytesread))) {
            ret = -1;
            printf( "ERROR: EVP_ENCRYPTUPDATEn");
        }
        encData_len = len;

        fwrite(encData, 1, encData_len, enc_file );
        // read more bytes
        bytesread = fread(origData, 1, aes_blocksize, orig_file);
    }
    // last step encryption
    if (!(EVP_EncryptFinal_ex(e_ctx, encData, &len))) {
        ret = -1;
        printf( "ERROR: EVP_ENCRYPTFINAL_EXn");
    }
    encData_len = len;

    fwrite(encData, 1, encData_len, enc_file );

    // free cipher
    EVP_CIPHER_CTX_free(e_ctx);

结论

通过实现类似于本文中描述的示例的代码,您可以快速学习如何使用 Java Crypto API 和 OpenSSL API 在基于 Intel® 处理器的 Android 平台上加密数据。

相关文章与资源

注意事项

本文档中提供的信息与英特尔产品相关。 本文档未以任何方式(明示或暗示)通过禁止反言或其他方式授予任何知识产权的许可。 除非在英特尔此类产品的销售条款和条件中另有规定,否则英特尔不承担任何责任,并且英特尔不声明与英特尔产品的销售和/或使用相关的任何明示或暗示的保证,包括与特定用途的适用性、适销性或侵犯任何专利、版权或其他知识产权相关的责任或保证。

除非 Intel 书面同意,否则 Intel 产品不设计也不用于任何可能导致人员伤亡的应用程序。

英特尔可随时更改规范和产品说明,恕不另行通知。 设计人员不得依赖标有“保留”或“未定义”的任何功能或指令的缺失或特征。 英特尔保留这些以供将来定义,并且对因其未来变更而产生的冲突或不兼容性不承担任何责任。 此处的信息如有更改,恕不另行通知。 请勿使用此信息来最终确定设计。

本文档中描述的产品可能包含已知为勘误的设计缺陷或错误,这可能导致产品偏离已发布的规范。当前的已表征勘误可应要求提供。

请联系您当地的英特尔销售办事处或您的经销商以获取最新的规范,并在下订单前进行咨询。

可以通过拨打 1-800-548-4725 或访问以下网址获取本文档中引用的、带有订单号的文档或英特尔其他文献的副本:http://www.intel.com/design/literature.htm

用于性能测试的软件和工作负载可能仅针对英特尔微处理器进行了优化。 性能测试(例如 SYSmark* 和 MobileMark*)使用特定的计算机系统、组件、软件、操作和功能进行衡量。 对任何这些因素的任何更改都可能导致结果有所不同。 您应该查阅其他信息和性能测试,以帮助您全面评估您考虑的购买,包括该产品与其他产品结合时的性能。

本文档中重印的任何软件源代码均根据软件许可证提供,并且只能根据该许可证的条款使用或复制。

英特尔、英特尔徽标和 Atom 是英特尔公司在美国和/或其他国家/地区的商标。

版权所有 © 2014 英特尔公司。保留所有权利。

*其他名称和品牌可能被声明为他人的财产。

要了解更多关于安卓开发者的英特尔工具,请访问英特尔® 安卓开发者专区

© . All rights reserved.