1. 程式人生 > 其它 >資料加密與安全專題《mbedtls工具篇,實用教程6@對大檔案使用加密解密演算法,再探MD5》

資料加密與安全專題《mbedtls工具篇,實用教程6@對大檔案使用加密解密演算法,再探MD5》

技術標籤:資料加密與安全專題大檔案md5md5mbedtls

前言

做嵌入式開發的同學知道,嵌入式片上記憶體RAM容量一般是比較小的,而經常需要對Flash裡面的大檔案做雜湊校驗,例如一個RAM 256KB的MCU,需要對512KB的Flash檔案做MD5、SHA256檢驗,這可怎麼辦,相信難道了不少工程師。再物聯網領域,這類情況最常見的無非在裝置升級(OTA)環節,因為OTA過程一般需要對檔案的完整性、合法性(簽名)進行驗證,下面說下如何使用mebdtls工具處理這類情況。

好使但不太建議的方法

如果對這類流式處理不熟悉的同學,估計首先會想到一個方法:在製作原檔案的時候,把大檔案進行拆分成若干個小資料包,每個小資料包後面追加本段的校驗結果(例如MD5)。這樣,接收方就能分片進行MD5校驗,以解決記憶體問題。的確,這個方法可以解決這個問題,但是有幾個弊端:

  • 需要額外的算法制作檔案包,耗時
  • 增加了額外的資料,佔用更多頻寬,丟包的風險增加(資料包越大,丟包風險越高)
  • 校驗、解密過程中,效率較低,相當於執行了N次演算法

對大檔案使用加密解密類演算法,再探MD5(校驗)

其實,演算法設計之初,就應該考慮這個問題,設計這些演算法的都是行業大咖,怎麼可能沒考慮到這一層面,於是,下面給出MD5分片處理的方法(其他演算法同理,不一一例舉)

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#include <stdio.h>
#define mbedtls_printf       printf
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
#endif

#if defined(MBEDTLS_MD5_C)
#include "mbedtls/md5.h"
#endif

#if !defined(MBEDTLS_MD5_C)
int main( void )
{
    mbedtls_printf("MBEDTLS_MD5_C not defined.\n");
    return( 0 );
}
#else
int main( void )
{
    int i;
    unsigned char digest[16];
    char str1[] = "Helloworld1";
    char str2[] = "Helloworld2";

	mbedtls_printf("\n  MD5('%s%s') = ", str1, str2);

    /**
     * MD5分片處理核心函式
     * */

    int ret;
	mbedtls_md5_context ctx;

	mbedtls_md5_init(&ctx);

	ret = mbedtls_md5_starts_ret(&ctx);

	ret = mbedtls_md5_update_ret(&ctx, (unsigned char*) str1, strlen(str1));

	ret = mbedtls_md5_update_ret(&ctx, (unsigned char*) str2, strlen(str2));

	ret = mbedtls_md5_finish_ret(&ctx, digest);

	mbedtls_md5_free(&ctx);

	/**************************************************************************/

    for( i = 0; i < 16; i++ )
        mbedtls_printf( "%02x", digest[i] );

    mbedtls_printf( "\n\n" );

#if defined(_WIN32)
    mbedtls_printf( "  Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( MBEDTLS_EXIT_SUCCESS );

	exit: return (ret);
}
#endif /* MBEDTLS_MD5_C */

執行得出結果:

與實際結果進行對比: