gpt4 book ai didi

c++ - Python 2.7 Test_SSL 失败 - RAND_status 为 0(随机性不足)

转载 作者:搜寻专家 更新时间:2023-10-31 01:03:55 25 4
gpt4 key购买 nike

我已将我的嵌入式 Python 应用程序嵌入到 marmalade C++ 中以供跨平台使用(Android、iOS、Windows 手机 8、黑莓 10)。 我在通过 HTTPS 连接到网站时遇到问题(HTTP 套接字工作)

预感

  • 我必须编写一个自定义随机函数,因为它应该是跨平台,使用/dev/random 是不可能的( posix问题太可能了)
  • 使用 marmalade api 有一个内置的跨平台随机数我在使用它生成时取得了良好效果的功能用于 AES 加密的 iv 位。

如果有人能阐明 ssl 需要多少随机性,以位为单位,或者它是否实际检查熵的程度????

test_ssl.py [回溯]

test_random (test_ssl.BasicTests) ...
RAND_status is 0 (insufficient randomness)


ok
test_refcycle (test_ssl.BasicTests) ... ERROR
test_sslwrap_simple (test_ssl.BasicTests) ... ok

======================================================================
ERROR: test_refcycle (test_ssl.BasicTests)
----------------------------------------------------------------------
----------------------------------------------------------------------
Ran 8 tests in 2.000s

test.test_support.TestFailed: Traceback (most recent call last):
File "./test_ssl.py", line 149, in test_refcycle
ss = ssl.wrap_socket(s)
File "/pythonHome/Lib/ssl.py", line 344, in wrap_socket
ciphers=ciphers)
File "/pythonHome/Lib/ssl.py", line 108, in __init__
socket.getpeername(self)
File "/pythonHome/Lib/socket.py", line 226, in meth
return getattr(self._sock,name)(*args)
error: [Errno 0] Error

接下来我测试了显而易见的:

test_random.py [回溯]

test_jumpahead (test_random.MersenneTwister_TestBasicOps) ... FAIL


======================================================================
FAIL: test_jumpahead (test_random.MersenneTwister_TestBasicOps)
----------------------------------------------------------------------
Traceback (most recent call last):
File "./test_random.py", line 58, in test_jumpahead
self.assertRaises(TypeError, self.gen.jumpahead, "ick") # wrong type
AssertionError: TypeError not raised

----------------------------------------------------------------------
Ran 60 tests in 34.000s

FAILED (failures=1)

test.test_support.TestFailed: Traceback (most recent call last):
File "./test_random.py", line 58, in test_jumpahead
self.assertRaises(TypeError, self.gen.jumpahead, "ick") # wrong type
AssertionError: TypeError not raised

据我所知,“test_jumpahead”函数用于在并行进程中需要熵的情况。即使我修补了随机函数,这也是它遇到的唯一问题。

C++ 自定义随机函数

PyObject* s3eRand(PyObject* self, PyObject* pArgs)
{
char* str2;
Py_ssize_t count;
if (!PyArg_ParseTuple(pArgs, "s#", &str2, &count)) return NULL;

IwRandSeed((int32)s3eTimerGetMs());
char str[5];

sprintf(str,"%d",IwRandMinMax(0, 255));
return Py_BuildValue("s",str);
}

static PyMethodDef PYs3eRandomMethods[] = {
{ "s3eUrandom", s3eRand, METH_VARARGS, "randomintiger" },
{ NULL, NULL, 0, NULL }
};

os.py [修改]

import s3ePY
...
...
if not _exists("urandom"):
def urandom(n):
"""urandom(n) -> str

Return a string of n random bytes suitable for cryptographic use.
_urandomfd = open("raw:///dev/urandom", O_RDONLY) doesnt work

"""
#from s3ePY import s3eUrandom

bs=b""
while n - len(bs) >= 1:
bs+=chr(int(s3ePY.s3eUrandom()))
return bs

最佳答案

RAND_status is 0 (insufficient randomness)

RAND_status失败,您应该调用 RAND_poll重新播种生成器,或者你应该调用 RAND_add添加你自己的熵。参见 Random Numbers在 OpenSSL wiki 上。


If anyone could shed some light on how much randomness is required for ssl..

它是底层生成器;不是 SSL。

这取决于生成器。默认生成器是 md_rand , 其源代码可以在 <openssl src>/crypto/rand/md_rand.c 中找到.如果您使用 md_rand ,那么您需要为生成器播种/重新播种至少 32 个字节:

$ grep -R ENTROPY_NEEDED *
...
crypto/rand/md_rand.c: if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
crypto/rand/md_rand.c: ok = (entropy >= ENTROPY_NEEDED);
crypto/rand/md_rand.c: ret = entropy >= ENTROPY_NEEDED;
crypto/rand/rand_lcl.h:#define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */
...

一些生成器不允许熵输入。例如,RDRAND 引擎无操作 RAND_add并总是返回成功。 (但这似乎不是你的问题)。

播种所需的大小(即 32 字节)是有意向您隐藏的。参见 RAND_status/RAND_seed在 OpenSSL 邮件列表上。请注意,128 位/16 字节不再是最小值。


C++ custom random function...

您应该创建一个引擎并将其插入 OpenSSL。然后 OpenSSL 将使用您的引擎而不是 md_rand引擎。

但是,这并没有灌输很多信心:

IwRandSeed((int32)s3eTimerGetMs());

没有人会想到暴力破解 time() ...等等,Wagner 和 Goldberg 在 1996 年对 Netscape 做到了。参见 Randomness and the Netscape Browser .

也许你应该混合 PID,这样它至少和 Netscape 的实现一样糟糕,而且不比 :) 差


你没有说你在什么平台上。下面是我用来从 iOS 上的传感器收集熵的代码。我有类似的 Android 代码。使用传感器数据让我即使在低熵设备上也能确保足够的熵。

获取传感器数据后,在每次使用生成器之前将其发送到随机数生成器。然后底层生成器执行熵扩展和提取(与您的 s3eRand 不同)。

代码是为 Crypto++ 编写的,但您需要做的就是交换 Crypto++ 的 IncorporateEntropy对于 OpenSSL 的 RAND_add .

static CryptoPP::RandomPool& GetRandomPool()
{
static CryptoPP::RandomPool pool;
static dispatch_once_t once = 0;

dispatch_once(&once, ^{
CryptoPP::SecByteBlock seed(32);
CryptoPP::OS_GenerateRandomBlock(true, seed.data(), seed.size());
pool.IncorporateEntropy(seed.data(), seed.size());
});

// First, send in all the uninitialized data. Then:
// sesnors[0,1,2] uses accelerometer, if available
// sesnors[3,4,5] uses gyroscope, if available
// sesnors[6,7,8] uses magnetometer, if available
CryptoPP::SecBlock<double> sensors(3 * 3);
pool.IncorporateEntropy(sensors.BytePtr(), sensors.SizeInBytes());

// See Event Handling Guide for iOS, Event Motions
// https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/motion_event_basics/motion_event_basics.html
CMMotionManager* mgr = [[CMMotionManager alloc] init];
if(mgr == nil) { return pool; }

// Start motion services
if([mgr isAccelerometerAvailable] != NO)
[mgr startAccelerometerUpdates];
if([mgr isGyroAvailable] != NO)
[mgr startGyroUpdates];
if([mgr isMagnetometerAvailable] != NO)
[mgr startMagnetometerUpdates];

// The components starts slowly... A pause less than about 0.150s
// will cause individual sensor data to return nil.
[NSThread sleepForTimeInterval:0.150f];

if([mgr isAccelerometerAvailable] != NO) {
CMAccelerometerData* accelData = [mgr accelerometerData];
if(accelData) {
sensors[0] = [accelData acceleration].x;
sensors[1] = [accelData acceleration].y;
sensors[2] = [accelData acceleration].z;
}
[mgr stopAccelerometerUpdates];
}

if([mgr isGyroAvailable] != NO) {
CMGyroData* gyroData = [mgr gyroData];
if(gyroData) {
sensors[3] = [gyroData rotationRate].x;
sensors[4] = [gyroData rotationRate].y;
sensors[5] = [gyroData rotationRate].z;
}
[mgr stopGyroUpdates];
}

if([mgr isMagnetometerAvailable] != NO) {
CMMagnetometerData* magnetData = [mgr magnetometerData];
if(magnetData) {
sensors[6] = [magnetData magneticField].x;
sensors[7] = [magnetData magneticField].y;
sensors[8] = [magnetData magneticField].z;
}
[mgr stopMagnetometerUpdates];
}

pool.IncorporateEntropy(sensors.BytePtr(), sensors.SizeInBytes());

[mgr release], mgr = nil;

#if !defined(NDEBUG)
NSLog(@"\n A: %f, %f, %f" \
@"\n G: %f, %f, %f" \
@"\n M: %f, %f, %f",
sensors[0], sensors[1], sensors[2],
sensors[3], sensors[4], sensors[5],
sensors[6], sensors[7], sensors[8] );
#endif

return pool;
}

如有兴趣,请调用CryptoPP::OS_GenerateRandomBlock结束对 /dev/urandom 的调用.但如您所见,它只调用一次,我不依赖它。如果它丢失了,例程仍然能够产生位。

关于c++ - Python 2.7 Test_SSL 失败 - RAND_status 为 0(随机性不足),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24970814/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com