为了更好地理解RSA,我一直在使用GunPG 1.4的源代码,特别是rsa.c文件中的RSA实现。正如标题所说,我无法弄清楚填充的位置。
通常在RSA中,填充在加密之前完成,并在解密期间取消。加密首先从第409行开始,我们看到
int
rsa_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
{
RSA_public_key pk;
if( algo != 1 && algo != 2 )
return G10ERR_PUBKEY_ALGO;
pk.n = pkey[0];
pk.e = pkey[1];
resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.n ) );
public( resarr[0], data, &pk );
return 0;
}
这似乎很容易,它将数据提供给公众"在220行上更高的功能。公共负责计算重要的(c = m ^ e mod n)过程。这一切看起来像:
static void
public(MPI output, MPI input, RSA_public_key *pkey )
{
if( output == input ) { /* powm doesn't like output and input the same */
MPI x = mpi_alloc( mpi_get_nlimbs(input)*2 );
mpi_powm( x, input, pkey->e, pkey->n );
mpi_set(output, x);
mpi_free(x);
}
else
mpi_powm( output, input, pkey->e, pkey->n );
}
等一下......现在看起来public正在将该计算的工作传递给位于mpi-pow.c文件中的mpi_powm()。我会饶有你的细节,但这个功能真的很长。
在所有这些地方某种类型的PKCS#1填充和取消填充(或类似的东西)正在发生,但我无法弄清楚我的生活在哪里。任何人都可以帮我看看填充发生的地方吗?
答案 0 :(得分:2)
为了更好地理解RSA,我一直在愚弄GnuPG 1.4的源代码,特别是rsa.c文件中的RSA实现。
既然你正在查看较旧的(< 2.0)内容,并且因为它仅用于学习目的,我宁愿建议你查看“ye olde rsaref.c from gnupg.org”,其中填充是以漂亮的方式实现的显而易见的方式。
......某种PKCS#1 ......
确切地说,GnuPG使用PKCS#1 v1.5(在RFC 4880中指定)。
嗯,让我们看看我是否可以在逻辑上把它包起来。根据PKCS#1 v1.5的GnuGP垫,所以它只是添加随机垫以满足长度要求。任何人都可以帮我看看填充的位置吗?
如果您查看cipher/pubkey.c
文件(其中包含rsa.h
文件),您会注意到pubkey_table_s
结构,该结构定义了定义的元素列表钥匙。 出于填充的原因,随机字节会附加到该列表(更好:在该结构之后)。它就是这样做的,因为通过查找列表的末尾可以很容易地删除那些随机字节。长话短说,random.c
可能开始对你更有意义。现在,所有这些东西(以及更多的东西)被编译成一个名为libcipher
的库......它本身被编译为由添加填充的函数使用,并以您期望的方式处理RSA。最后,编译后的可执行文件使用libcipher提供的函数来处理填充 - 具体取决于填充的个别需求。
所以你目前期望在1或2中找到,也许3个文件实际上分布在超过6个文件中...我认为这不是你学习努力的最佳基础。如上所述,出于参考目的,我会选择他们曾经开始使用的旧 rsaref.c。
不确定这是否真的提供了你想要获得的所有细节,但它应该给你一个良好的单挑......希望它有所帮助。
答案 1 :(得分:1)
GPG 1.4根本不使用任何填充。它加密原始会话密钥。