【发布时间】:2011-11-18 10:21:25
【问题描述】:
我在 Java 客户端中使用公钥时遇到了一些奇怪的问题。我从 C 服务器获取公钥,我知道以下内容:B64Encoded,X.509 RSA 密钥,我应该使用 PKCS1Padding。到目前为止,我已经做了以下工作,以确保客户端和服务器之间传输的数据是正确的:
1) 服务端发送的数据内容和长度与java客户端一致
2) B64解码后,数据和长度一致
3) 我还验证了 C 客户端和 Java 客户端之间的数据是相同的,直到我开始从解码的数据创建公钥。
我遇到了一个问题,即 Java 客户端在 Cipher 加密密码后将太多数据发送回服务器。我尝试使用不同的方法来创建公钥对象,但似乎没有任何效果。我要么收到“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 客户端使用 BASE64decoded 公钥加密并尝试复制之前,我应该更多地了解它对 BASE64decoded 公钥所做的事情?现在我无法访问该部分:(
我尝试使用不同的 KeySpecs、PublicKeys 和 paddings,但结果总是相同的(尽管当我使用 KeySpec 时,异常可能会有所不同)。
否则服务器和客户端之间的通信可以正常工作。只是这部分使用了不起作用的公钥。
编辑:只是想添加公钥字符串,如果这说明了什么:
Public key from server:
MIGIAoGBAMZawVoP6mHl0xD3Epn1l4S/6Ke20ZTNLKaXyi425NwhiE7LoTysAcpx
y3i9LXLVNGpdPNtpGD3mvlNJc/HfGQQ7NQpNyKpe5EzsODb1YCbODtfmaRODDW9B
qsrE8DCxI0g8gzu3NJTrUh4NfRaSBn9HaOnBUwiyQyihq2I6MB6bAgJWXw==
【问题讨论】:
-
您是否处于对开发人员不友好的奇怪环境中?任何体面的 IDE 都会告诉您发生异常的位置,而无需包装每条语句。
-
你这样做: String keyString = new String(pk); getKeyFromServer(); 返回的数据是如何编码的?根据其编码方式,new String(pk) 可能会破坏您的数据?
-
Marcelo:将代码分解为多个 try/catch 只是我在执行此操作时喜欢做的事情。我以后会清理这样的东西。 @nojo 我尝试解码 byte[],但是当我将该输出与从 C 客户端获得的输出进行比较时,它是不同的,我遇到了同样的问题。
-
请注意 String.getBytes() 和 String(byte[]) 构造函数在与使用默认平台编码的程序以外的任何东西进行通信时永远不应该使用(即使使用是有问题的)然后)。您没有发送回编码字符而不是字节,是吗?
-
顺便说一句,如果可以实例化密钥,那么密钥不正确的可能性确实非常小,更有可能 Cipher.doFinal() 的输入或输出是罪魁祸首,或者之后数据的编码。
标签: java c cryptography rsa