我正在keil microvision IDE中使用STM32F103E arm cortex-m3 MCU開發項目。
我需要爲某些目的生成隨機數,但我不想使用標準C++庫生成的僞隨機數,所以我需要一種方法來使用硬件功能生成REAL隨機數,但我不知道我該怎麼做。
有什麼想法? (我是軟件工程師&不是電子專業人員,所以請簡單描述一下:P)如何使用STM32 MCU生成REAL隨機數?
回答
正如指出的那樣,該芯片沒有硬件RNG。
但你可以推出自己的。通常的做法是測量獨立時鐘之間的抖動。獨立意味着這兩個時鐘由不同的基準或RC振盪器支持,而不是來自相同的。
我會使用:
-
從系統時鐘(MHz範圍內)
- 其中千赫範圍RC振盪器
設置一個計數器在千赫衍生
要從中得到隨機數,請使用正常的僞RNG。使用上面收集的熵來不可預測地改變僞RNG的內部狀態。對於密鑰生成,不要一次讀取所有位,但允許發生幾個突變。
對此的攻擊是顯而易見的:如果攻擊者可以測量或控制kHz範圍的RC振盪器達到MHz精度,則隨機性會消失。如果您擔心這一點,請使用智能卡或其他安全協處理器。
F1系列似乎沒有RNG(硬件隨機數發生器),所以你唯一的選擇是使用僞隨機數或詢問外部輸入(有些人認爲例如人的手部動作是隨機的)。你通常使用一些加密庫而不是標準C++庫來獲得更好的僞隨機數。
這是一個老問題,我剛剛碰到,但我想回答,因爲我沒有找到其他答案令人滿意。
「我需要用於RSA密鑰生成的隨機數字。」
這意味着PRNG例程(通常被錯誤地稱爲RNG,我的寵物)是UNACCEPTABLE,並且不會提供所需的安全性。
一個外部真正的RNG是可以接受的,但最優雅的答案是切換到一個STM32F2xx或STM32F4xx微控制器,它有一個內置的TRUE隨機數發生器,專門用於這種應用。對於開發,我想你可以使用thr F1和任何PRNG,但是在使用真正的RNG之前,會出現「它工作,讓我們發貨」的誘惑,當RIGHT組件(當然是ST F4,我認爲在問這個問題之前,F2芯片也已經存在了)。由於非技術原因(該芯片已經被指定,OP沒有對所需功能的輸入),這個答案可能是不可接受的,但是選擇芯片的人應該根據片上外設和功能選擇它應用程序需要。
我發現並測試了另一種方法,效果很好。它可以生成真正的隨機32位數字,我從來沒有檢查過它的速度,可能每個數字需要幾毫秒。這是怎麼一回事呢:
- 閱讀以最快的速度可能嘈雜的內部溫度,以產生最大的ADC噪聲
- 運行通過硬件CRC發生器的值,在大多數(全部?)STM32芯片 可用
重複幾次,我發現8次給了很好的隨機性。我通過按升序對輸出值進行排序並將它們繪製在excel中來檢查隨機性,隨機數字很好產生一條直線,不確定的隨機性或某些數字的「聚集」立即可見。 這裏是爲STM32F03代碼:
uint32_t getTrueRandomNumber(void) {
ADC_InitTypeDef ADC_InitStructure;
//enable ADC1 clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// Initialize ADC 14MHz RC
RCC_ADCCLKConfig(RCC_ADCCLK_HSI14);
RCC_HSI14Cmd(ENABLE);
while (!RCC_GetFlagStatus(RCC_FLAG_HSI14RDY))
;
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO; //default
ADC_Init(ADC1, &ADC_InitStructure);
//enable internal channel
ADC_TempSensorCmd(ENABLE);
// Enable ADCperipheral
ADC_Cmd(ADC1, ENABLE);
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN) == RESET)
;
ADC1->CHSELR = 0; //no channel selected
//Convert the ADC1 temperature sensor, user shortest sample time to generate most noise
ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor, ADC_SampleTime_1_5Cycles);
// Enable CRC clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
uint8_t i;
for (i = 0; i < 8; i++) {
//Start ADC1 Software Conversion
ADC_StartOfConversion(ADC1);
//wait for conversion complete
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)) {
}
CRC_CalcCRC(ADC_GetConversionValue(ADC1));
//clear EOC flag
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
}
//disable ADC1 to save power
ADC_Cmd(ADC1, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE);
return CRC_CalcCRC(0xBADA55E5);
}
你的方法有缺陷。在白化(CRC)之後,您無法通過查看輸出*來確定熵源(ADC)的質量。此外,輸出值的簡單直方圖只會檢測RNG中最簡單的缺陷。事實上,你需要8輪產生的東西,即使*看起來隨機乍一看錶明,你得到很小的熵每個ADC樣本,如果有的話。因此,沒有進一步的分析,你不能對RNG的熵做任何假設,因此不能用它來生成密碼密鑰。 – JimmyB 2017-01-10 14:13:05
- 1. 谷歌測試裸機stm32 MCU
- 2. 在隨機生成50個隨機數中使用隨機數#
- 3. 生成隨機數
- 4. 生成隨機數
- 5. 生成隨機數
- 6. 如何用arc4random生成隨機數字?
- 7. 如何用PHP生成隨機數?
- 8. 如何使用xslt生成隨機UUID
- 9. 隨機數生成
- 10. 隨機數生成
- 11. 生成幾何隨機數
- 12. 使用Matlab生成奇數隨機數
- 13. 隨機數生成使用srand()函數
- 14. 生成隨機數
- 15. 隨機數生成機制
- 16. 用jinja2生成隨機數
- 17. 使用sed在隨機數行中生成隨機數
- 18. 如何生成隨機UIColor?
- 19. 如何生成隨機圖?
- 20. 隨機數生成器幫助不生成隨機數 - C
- 21. 如何從短隨機數生成更長的隨機數?
- 22. 生成隨機數:計算隨機生成的x次數
- 23. 隨機()不生成隨機數
- 24. 使用C++生成隨機數TR1
- 25. 使用SHA多次生成隨機數
- 26. 使用Node.js生成隨機數頁面
- 27. 使用doSMP生成隨機數
- 28. 使用javascript隨機生成數字
- 29. 使用ActionScript-3生成隨機數
- 30. 使用Python,ArcGIS 10.1生成隨機數
貴芯片/電路板有硬件RNG? – Mat 2013-02-10 09:45:40
你需要什麼隨機數? – starblue 2013-02-10 09:50:00
我需要用於RSA密鑰生成的隨機數字。正如Jari所說,似乎F1系列沒有RNG,但我想知道是否有任何方法可以使用其他硬件功能(例如RTC)來模擬硬件RNG? – 2013-02-10 10:30:07