java - 在服务器端解密加密消息
问题描述
我正在开发一个客户端-服务器应用程序。我必须使用非对称密码术。客户端加密他的消息并创建数字签名。
我将消息和签名存储在 Vector 中,然后将此 Vector 发送到服务器。服务器接收到这个向量。
在服务器端,首先我检查签名以查看服务器是否正在与正确的客户端通信,当签名良好时,我正在尝试解密消息,但此解密的结果并不好。问题仅涉及加密/解密,其余代码没有问题。
客户端:
private void payActionPerformed(java.awt.event.ActionEvent evt) {
DataInputStream dis = new DataInputStream(s.getInputStream());
ObjectOutputStream dos = new ObjectOutputStream(s.getOutputStream());
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] message = concatMess.getBytes("UTF-8");
cipherText = encryptCipher.doFinal(message);
texteCrypteStr= Base64.getEncoder().encodeToString(cipherText);
System.out.println("MESSAGE: "+cipherText);
//SIGNATURE DU MESSAGE
Signature signature = Signature.getInstance("SHA1withRSA","BC");
System.out.println("Initialisation de la signature");
signature.initSign(keyPri);
System.out.println("Hachage du message");
signature.update(cipherText);
System.out.println("Generation des bytes");
bytesign = signature.sign();
String texteSignStr= Base64.getEncoder().encodeToString(bytesign);
System.out.println("CLIENT SIGNATURE: "+texteSignStr);
Vector vecByte = new Vector();
vecByte.add(bytesign);
vecByte.add(cipherText);
dos.writeObject(vecByte);
received = dis.readUTF();
}
服务器端:
public class PaiementHandler{
Vector<byte[]> receivedVec = new Vector<byte[]>();
String toreturn;
receivedVec = ((Vector)disr.readObject());
System.out.println("v1 "+receivedVec.get(0));
System.out.println("v2 "+receivedVec.get(1));
Vector<String> received = null;
//RECUPERATION CLE PUBLIQUE
KeyStore ksv = null;
ksv = KeyStore.getInstance("PKCS12", "BC");
ksv.load(new FileInputStream("C:\\Users\\user\\Desktop\\KEYSTORE\\keystore.p12"),"gogo".toCharArray());
System.out.println("Recuperation du certificat");
X509Certificate certif = (X509Certificate)ksv.getCertificate("toto");
System.out.println("Recuperation de la cle publique");
PublicKey publicKey = certif.getPublicKey();
//VERIFICATION DE LA SIGNATURE
System.out.println("\nVérification de la signature");
System.out.println("*** Cle publique recuperee = "+publicKey.toString());
System.out.println("Debut de verification de la signature construite");
Signature signature = Signature.getInstance("SHA1withRSA", "BC");
signature.initVerify(publicKey);
signature.update(receivedVec.get(1));
System.out.println("Verification de la signature construite");
boolean ok = signature.verify(receivedVec.get(0));
if(ok){
System.out.println("signature verified with success");
//DECHIFFREMENT DU MESSAGE
try{
Cipher dechiffrement = Cipher.getInstance("RSA", "BC");
dechiffrement.init(Cipher.DECRYPT_MODE,publicKey);
System.out.println("AVANT DECH");
byte[] texteDecode = dechiffrement.doFinal(receivedVec.get(1));
String texteDecodeStr = new String(texteDecode, "UTF-8");
System.out.println("Vecteur: "+texteDecodeStr);
}
}
这是客户端发送给服务器的消息:“2222-2222-2222.30 3 1 1 2019-07-30 2019-07-31 90 40”。因此,此消息被加密并与客户端签名一起以向量形式发送到服务器(它们都是字节 [])。
服务器接收到这个向量,它首先检查签名,当它没问题时,它会解密消息。这是在 String 中翻译时的解密结果:
��������5�&�]��{��^��S?u2_��l��i������������b#��fCA�5�Ri,& �P �T��3�4��:����Rm���~�W���DG��ga��i����vR
我不明白为什么我有这个结果......我正在尝试像这个网站一样对其进行编码https://www.devglan.com/online-tools/rsa-encryption-decryption但我不知道在哪里问题
解决方案
由于这个原因,我找到了解决方案:https ://gist.github.com/nielsutrecht/855f3bef0cf559d8d23e94e2aecd4ede
我必须在 base64 中对加密消息的结果进行编码并在解密之前对其进行解码。
客户端:
Cipher encryptCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
String concatMess="";
int k = 0;
while(k<vec.size()){
concatMess+=vec.get(k);
if(k+1<vec.size())
concatMess+="!";
k+=1;
}
System.out.println("VECTOR:"+concatMess);
byte[] message = concatMess.getBytes(StandardCharsets.UTF_8);
cipherText = encryptCipher.doFinal(message);
System.out.println("MESSAGE byte: "+cipherText);
cipherTextString = Base64.getEncoder().encodeToString(cipherText);
服务器端 :
Cipher dechiffrement = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", "BC");
dechiffrement.init(Cipher.DECRYPT_MODE,keyPri);
System.out.println("AVANT DECH");
byte[] texteDecode = dechiffrement.doFinal(Base64.getDecoder().decode((String)receivedVec.get(1)));
String texteDecodeStr = new String(texteDecode, StandardCharsets.UTF_8);
感谢这个解决方案,我得到了正确的信息。感谢您的建议和解释。
推荐阅读
- javascript - 数组中每小时的平均值
- server - 如何在 Centos7 服务器上附加额外的卷
- excel - 具有计数约束的 Excel Solver LP
- dart - Future builder(future:) 正在递归我的 http 请求,
- python - 我的主机上的套接字编程问题
- php - array_keys 除了正确的结果返回错误的结果
- amazon-web-services - AWS CodePipeline:如何获得一个阶段的最后一次成功执行?
- powershell - PowerShell:用户未登录时系统找不到文件
- django - 使用 Django Rest Framework 向远程服务发出 post 请求
- c# - Asp.Net Core WebApi 的身份验证失败并显示“Unprotect ticket failed”