使用从Java客户端中的C服务器接收的公钥

时间:2011-11-18 10:21:26

标签: java c cryptography rsa

我在Java客户端中使用公钥时遇到了一些奇怪的问题。我从C服务器获取公钥,我知道以下内容:B64Encoded,X.509 RSA密钥,我应该使用PKCS1Padding。到目前为止,我已完成以下操作,以确保在客户端和服务器之间传输的数据是正确的:

1)从服务器发送的数据内容和长度与java客户端

相同

2)一旦它被B64解码,数据和长度是相同的

3)我还验证了C客户端和Java客户端之间的数据是一样的,直到我开始从解码数据创建公钥。

我遇到了一个问题,即在Cipher加密密码后,Java客户端会将过多的数据发送回服务器。我试图在创建公钥对象时使用不同的方法,但似乎没有任何效果。我要么得到“ algid解析错误,而不是序列” - 错误,或者密钥被创建,我最终发送了太多字节的数据(来自Java的139与来自C客户端的128) 。 这是代码(剪掉一些不相关的东西)。一切都被分解为单一尝试/捕获,因为我试图找出问题所在:

byte[] pk = getKeyFromServer(); // 191 bytes 
String keyString = new String(pk);
byte[] decoded = decode(keyString); // 139 bytes

try {
    keySpec = new X509EncodedKeySpec(decoded);
} catch (Exception e) {  e.printStackTrace();}

try {
    keyFactory = KeyFactory.getInstance("RSA", "IBMJCE");
} catch (Exception e) {  e.printStackTrace();}

try {
    publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (Exception e) {  e.printStackTrace();}

try {
    cipher = Cipher.getInstance("RSA/SSL/PKCS1Padding", "IBMJCE");
} catch (Exception e) { e.printStackTrace(); }

try {
   cipher.init(Cipher.ENCRYPT_MODE, publicKey);
} catch (Exception e) { e.printStackTrace(); }

try {   sendEncrypted(cipher.doFinal(pwd.getBytes()));
} catch (Exception e) { e.printStackTrace(); }

上面的代码遇到了我之前提到过的异常,如果我删除了KeySpec和KeyFactory部分,并按照以下内容进入加密部分,但后来我发送了太多数据,而且服务器不能解密它(我从挖掘中获得了指数)。

java.math.BigInteger modulus = new java.math.BigInteger(decoded);
java.math.BigInteger exponent = new java.math.BigInteger("22111");

publicKey = new RSAPublicKey(modulus, exponent);

所以我想问题是,我做了一些完全错误的事情,或者是否有一些事情我应该更多地了解C客户端在使用它加密之前对BASE64解码的公钥做了什么,并尝试复制?现在我无法访问该部分:(

我尝试使用不同的KeySpecs,PublicKeys和paddings,但结果总是相同的(尽管异常可能会因我使用KeySpec而偏离基础而不同。)

服务器和客户端之间的通信运行良好。只是这部分使用了无效的公钥。

编辑:只是想添加公钥String,如果有的话:

Public key from server:
MIGIAoGBAMZawVoP6mHl0xD3Epn1l4S/6Ke20ZTNLKaXyi425NwhiE7LoTysAcpx
y3i9LXLVNGpdPNtpGD3mvlNJc/HfGQQ7NQpNyKpe5EzsODb1YCbODtfmaRODDW9B
qsrE8DCxI0g8gzu3NJTrUh4NfRaSBn9HaOnBUwiyQyihq2I6MB6bAgJWXw==

1 个答案:

答案 0 :(得分:1)

你可以试试“RSA / ECB / PKCS1Padding”而不是中间的“/ SSL”吗?如果我没有弄错的话,SSL会使用特殊的结构。

另外: 编码不兼容X509!似乎密钥的编码是PKCS#1,而X509使用围绕该编码的小包装器!

来自PKCS#1:

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

来自X509EncodedKeySpec:

SubjectPublicKeyInfo ::= SEQUENCE {
   algorithm AlgorithmIdentifier,
   subjectPublicKey BIT STRING }

因此,您必须在您收到的数据前面添加序列标签,长度,算法标识符和BIT STRING标签和长度!奇怪的是,你可以让它做任何事情。

对于这个特定的keylength和(奇怪的)两个字节的公共指数,标题将包含以下字节:

(byte) 0x30, (byte) 0x81, (byte) 0x9E, (byte) 0x30, (byte) 0x0D, (byte) 0x06, (byte) 0x09, (byte) 0x2A,
(byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7, (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x01,
(byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8C, (byte) 0x00, 

或者,您也可以从结构中检索两个整数,并从中创建RSAPublicKeySpec