【问题标题】:decryption of encrypted messages on the server side在服务器端解密加密消息
【发布时间】:2019-07-30 21:23:24
【问题描述】:

我正在开发一个客户端-服务器应用程序。我必须使用非对称密码术。客户端加密他的消息并创建数字签名。

我将消息和签名存储在 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”。因此,此消息被加密,并与客户端签名一起以向量形式发送到服务器(它们都是 byte[])。

服务器接收到这个向量,它首先检查签名,当它没问题时,它会解密消息。 以下是转换成 String 时的解密结果:

������u�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 那样对其进行编码,但我不知道问题出在哪里

【问题讨论】:

  • 您在编码和解码时指定 UTF-8(很好,但您可能希望使用 StandardCharsets.UTF_8 而不是“UTF-8”),但是当您将消息打印出来时,它正在被打印无论每个系统上的平台默认字符集是什么,都可能被您正在查看结果的终端仿真器解释为不同的编码。您可能需要检查数据的哈希值,看看它是否真的不同。
  • 这有点乱。核心问题是你试图用公钥解密。请记住:您使用 您的 私钥签名并使用收件人的公钥进行加密。接收者使用你的公钥验证并使用他的私钥解密。你们不共享一个密钥对,这完全违背了非对称加密的目的。在你得到这个概念后,你应该对此进行许多重要的改进。
  • 扔掉它并使用 TLS。它比您的方案安全得多。如果您需要数字签名,请使用SignedObject
  • @DavidConrad 所以问题可能来自字符编码/解码?我对这些有一些困难
  • 首先,不要依赖默认值。始终将完整的算法/模式/填充转换字符串指定为Cipher.getInstance()。其次,我不确定您为什么在这里和那里使用“BC”提供程序,但不是到处使用。除非您有充分的理由指定提供者,否则不要指定提供者。我没有看到。

标签: java encryption cryptography digital-signature encryption-asymmetric


【解决方案1】:

多亏了这个,我找到了解决方案: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);

感谢这个解决方案,我得到了正确的信息。 感谢您的建议和解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    相关资源
    最近更新 更多