2013-07-20 118 views
0

如何将大整数转换为java密码库的密钥? 我正在尝试使用我为AES加密的密钥值生成的共享diffie hellman密钥。将BigInteger转换为密钥

下面是我用

BigInteger bi; long value = 1000000000; 

BI = BigInteger.valueOf(值)的代码; Key key = new Key(bi);

但是它没有工作。 我可以知道如何将BigInteger值转换为Key值?

在此先感谢!

+0

这是家庭作业,是不是? – devnull

+0

'Key'是一个接口,你不能实例化它 – fge

回答

2

首先,你不能施放它。 BigInteger类和Key接口之间没有关系。其次,Key是一个接口不是类,所以你不能创建它的实例。你需要创建的是一些实现Key的类的实例。它很可能需要成为一个特定的实现类,而不是(比如说)一个匿名类。

最后一点是,Java加密API旨在隐藏密钥的表示形式。要从字节创建密钥,您需要创建一个KeySpec对象;例如SecretKeySpec(byte[] key, String algorithm)),然后使用KeyFactory从中“生成”一个密钥。典型的KeySpec构造函数以byte[]作为参数,因此您首先需要从BigInteger实例中获取字节数组。

1

您需要将BigInteger转换为特定大小的字节数组,然后使用第一个(最左边的)字节创建一个密钥。为此,您需要知道DH中使用的素数p的大小,因为该值需要左填充以表示密钥。我建议使用标准化的DH参数(或者至少确保素数的大小可以被8除)。

注意,有可能在使用BigInteger.toByteArray()因为返回的值是检索到的字节数组前面的零值字节编码作为签署(二补数)大端字节数组。如果结果大于素数(以字节为单位),则需要删除该字节。

public static byte[] encodeSharedSecret(final BigInteger sharedSecret, final int primeSizeBits) { 

    // TODO assignment add additional tests on input 

    final int sharedSecretSize = (primeSizeBits + Byte.SIZE - 1)/Byte.SIZE; 

    final byte[] signedSharedSecretEncoding = sharedSecret.toByteArray(); 
    final int signedSharedSecretEncodingLength = signedSharedSecretEncoding.length; 

    if (signedSharedSecretEncodingLength == sharedSecretSize) { 
     return signedSharedSecretEncoding; 
    } 

    if (signedSharedSecretEncodingLength == sharedSecretSize + 1) { 
     final byte[] sharedSecretEncoding = new byte[sharedSecretSize]; 
     System.arraycopy(signedSharedSecretEncoding, 1, sharedSecretEncoding, 0, sharedSecretSize); 
     return sharedSecretEncoding; 
    } 

    if (signedSharedSecretEncodingLength < sharedSecretSize) { 
     final byte[] sharedSecretEncoding = new byte[sharedSecretSize]; 
     System.arraycopy(signedSharedSecretEncoding, 0, 
       sharedSecretEncoding, sharedSecretSize - signedSharedSecretEncodingLength, signedSharedSecretEncodingLength); 
     return sharedSecretEncoding; 
    } 

    throw new IllegalArgumentException("Shared secret is too big"); 
} 

之后,您需要使用某种密钥导出方案导出密钥字节。应使用一个依赖于要实现的标准:

RFC 2631

X9.42说明提供了用于产生一个基本上任意 量从ZZ密钥材料的算法。我们的算法是通过强制使用某些可选字段并省略其他字段从而得到的。

KM = H (ZZ || OtherInfo) 

H是消息摘要函数SHA-1 [FIPS-180] ZZ是在第2.1.1节中计算出的共享 秘密值。前导零必须是
保留,以便ZZ占用与p一样多的八位组。

注意,我在充气城堡库发现一个bug高达1.49(这是在此日期当前版本)中关于秘密提取DH实现 - 它并剥离假龙头00H值字节,但它忘记了将结果留给最大尺寸p。这将导致不正确的派生密钥曾经在192倍(!)