密钥生成 Java、加密 php、解密 Java
Keygeneration Java, Encryption php, Decryption Java
我正在开发一个带有 java 客户端和 php 服务器的软件。 java 客户端生成 2 个 RSA 密钥。 public 密钥通过 post 请求发送到 php 服务器端。服务器使用 public 密钥加密响应并将其发送回 java 客户端。
但是我得到这个错误:
Exception in thread "main" org.bouncycastle.crypto.InvalidCipherTextException: unknown block type
at org.bouncycastle.crypto.encodings.PKCS1Encoding.decodeBlock(Unknown Source)
at org.bouncycastle.crypto.encodings.PKCS1Encoding.processBlock(Unknown Source)
据我通过谷歌搜索,public 和私钥不匹配。
此行出现错误:(应解密响应的位置)
byte[] encodedCipher = asymmetricBlockCipher.processBlock(messageBytes, 0, messageBytes.length);
所以事实上,我认为 public 密钥的 Base64 编码或它的传输一定有问题,但我找不到。如果我 echo
服务器上的编码密钥,它与客户端上的编码相同。但是在过去的几个小时里,我没有发现任何关于 base64 加密的有用信息。
对于 java 中的 Base64,我使用这个 2 类:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
我的部分 java 客户:
密钥已生成:(它们被保存为字段)
从这里开始:http://www.mysamplecode.com/2011/08/java-generate-rsa-key-pair-using-bouncy.html
private String publicKey;
private byte[] privateKey;
private void generateKeys() throws NoSuchProviderException, NoSuchAlgorithmException {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
BASE64Encoder base64Encoder = new BASE64Encoder();
SecureRandom rnd = new FixedRand();
generator.initialize(2048, rnd);
KeyPair keyPair = generator.generateKeyPair();
this.publicKey = base64Encoder.encode(keyPair.getPublic().getEncoded()).replaceAll("(?:\r\n|\n\r|\n|\r)", "").trim();
this.privateKey = keyPair.getPrivate().getEncoded();
}
Post 请求:(使用 apache http 客户端)
private String readUrl(String urlString, String publicKey) throws Exception {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urlString);
List<NameValuePair> nameValuePairs = new ArrayList<>(1);
nameValuePairs.add(new BasicNameValuePair("key", publicKey));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
StringBuffer responseString = new StringBuffer();
while ((line = rd.readLine()) != null) {
responseString.append(line);
}
return responseString.toString();
}
解密部分:
private String decrypt(String crypted) throws IOException, InvalidCipherTextException {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
AsymmetricBlockCipher asymmetricBlockCipher = new RSAEngine();
asymmetricBlockCipher = new org.bouncycastle.crypto.encodings.PKCS1Encoding(asymmetricBlockCipher);
BASE64Decoder base64Decoder = new BASE64Decoder();
crypted = new String(base64Decoder.decodeBuffer(crypted));
AsymmetricKeyParameter asymmetricKeyParameter = PrivateKeyFactory.createKey(this.javaKeyToBouncycastle(privateKey));
asymmetricBlockCipher.init(false, asymmetricKeyParameter);
byte[] messageBytes = crypted.getBytes();
byte[] encodedCipher = asymmetricBlockCipher.processBlock(messageBytes, 0, messageBytes.length);
return new String(encodedCipher);
}
private PrivateKeyInfo javaKeyToBouncycastle(byte[] key) throws IOException {
ASN1InputStream pkstream = new ASN1InputStream(key);
return PrivateKeyInfo.getInstance(pkstream.readObject());
}
我的 php 服务器的一部分:(使用 phpseclib)
$key = trim(base64_decode($_POST['key'], true));
$rsa = new Crypt_RSA();
$rsa->loadKey($key);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$crypt = $rsa->encrypt("Hello World");
echo base64_encode($crypt);
谢谢 :-)
不幸的是,我不太了解加密 atm 以及我在 google 中找到并自定义它们的大部分代码部分,但我正在研究它。 (仅限私人项目)
您不应将 base 64 编码的结果包装到字符串中。
crypted = new String(base64Decoder.decodeBuffer(crypted));
...
byte[] messageBytes = crypted.getBytes();
即使您在此之前执行 base 64 解码,字符串也无法保存随机数据,因为并非所有数据都代表有效的编码字符串。而只是将字节数组分配给一个新变量,例如
byte[] ciphertext = base64Decoder.decodeBuffer(crypted);
并将其用作 asymmetricBlockCipher
的输入。
我正在开发一个带有 java 客户端和 php 服务器的软件。 java 客户端生成 2 个 RSA 密钥。 public 密钥通过 post 请求发送到 php 服务器端。服务器使用 public 密钥加密响应并将其发送回 java 客户端。 但是我得到这个错误:
Exception in thread "main" org.bouncycastle.crypto.InvalidCipherTextException: unknown block type
at org.bouncycastle.crypto.encodings.PKCS1Encoding.decodeBlock(Unknown Source)
at org.bouncycastle.crypto.encodings.PKCS1Encoding.processBlock(Unknown Source)
据我通过谷歌搜索,public 和私钥不匹配。
此行出现错误:(应解密响应的位置)
byte[] encodedCipher = asymmetricBlockCipher.processBlock(messageBytes, 0, messageBytes.length);
所以事实上,我认为 public 密钥的 Base64 编码或它的传输一定有问题,但我找不到。如果我 echo
服务器上的编码密钥,它与客户端上的编码相同。但是在过去的几个小时里,我没有发现任何关于 base64 加密的有用信息。
对于 java 中的 Base64,我使用这个 2 类:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
我的部分 java 客户:
密钥已生成:(它们被保存为字段)
从这里开始:http://www.mysamplecode.com/2011/08/java-generate-rsa-key-pair-using-bouncy.html
private String publicKey;
private byte[] privateKey;
private void generateKeys() throws NoSuchProviderException, NoSuchAlgorithmException {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
BASE64Encoder base64Encoder = new BASE64Encoder();
SecureRandom rnd = new FixedRand();
generator.initialize(2048, rnd);
KeyPair keyPair = generator.generateKeyPair();
this.publicKey = base64Encoder.encode(keyPair.getPublic().getEncoded()).replaceAll("(?:\r\n|\n\r|\n|\r)", "").trim();
this.privateKey = keyPair.getPrivate().getEncoded();
}
Post 请求:(使用 apache http 客户端)
private String readUrl(String urlString, String publicKey) throws Exception {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urlString);
List<NameValuePair> nameValuePairs = new ArrayList<>(1);
nameValuePairs.add(new BasicNameValuePair("key", publicKey));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
StringBuffer responseString = new StringBuffer();
while ((line = rd.readLine()) != null) {
responseString.append(line);
}
return responseString.toString();
}
解密部分:
private String decrypt(String crypted) throws IOException, InvalidCipherTextException {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
AsymmetricBlockCipher asymmetricBlockCipher = new RSAEngine();
asymmetricBlockCipher = new org.bouncycastle.crypto.encodings.PKCS1Encoding(asymmetricBlockCipher);
BASE64Decoder base64Decoder = new BASE64Decoder();
crypted = new String(base64Decoder.decodeBuffer(crypted));
AsymmetricKeyParameter asymmetricKeyParameter = PrivateKeyFactory.createKey(this.javaKeyToBouncycastle(privateKey));
asymmetricBlockCipher.init(false, asymmetricKeyParameter);
byte[] messageBytes = crypted.getBytes();
byte[] encodedCipher = asymmetricBlockCipher.processBlock(messageBytes, 0, messageBytes.length);
return new String(encodedCipher);
}
private PrivateKeyInfo javaKeyToBouncycastle(byte[] key) throws IOException {
ASN1InputStream pkstream = new ASN1InputStream(key);
return PrivateKeyInfo.getInstance(pkstream.readObject());
}
我的 php 服务器的一部分:(使用 phpseclib)
$key = trim(base64_decode($_POST['key'], true));
$rsa = new Crypt_RSA();
$rsa->loadKey($key);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$crypt = $rsa->encrypt("Hello World");
echo base64_encode($crypt);
谢谢 :-) 不幸的是,我不太了解加密 atm 以及我在 google 中找到并自定义它们的大部分代码部分,但我正在研究它。 (仅限私人项目)
您不应将 base 64 编码的结果包装到字符串中。
crypted = new String(base64Decoder.decodeBuffer(crypted));
...
byte[] messageBytes = crypted.getBytes();
即使您在此之前执行 base 64 解码,字符串也无法保存随机数据,因为并非所有数据都代表有效的编码字符串。而只是将字节数组分配给一个新变量,例如
byte[] ciphertext = base64Decoder.decodeBuffer(crypted);
并将其用作 asymmetricBlockCipher
的输入。