java - 非对称算法使用的问题

标签 java encryption cryptography

我尝试使用非对称加密在客户端使用公钥加密消息,并在服务器端使用私钥解密。

解密消息后,它与平台文本不匹配。你能帮我解决这个问题吗?

下面是代码:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class GenerateKeys {

    public static void saveToFile(String fileName, BigInteger mod,
            BigInteger exp) throws IOException {
        ObjectOutputStream oout = new ObjectOutputStream(
                new BufferedOutputStream(new FileOutputStream(fileName)));
        try {
            oout.writeObject(mod);
            oout.writeObject(exp);
        } catch (Exception e) {
            throw new IOException("Unexpected error", e);
        } finally {
            oout.close();
        }
    }

    public static void rsaKeyGeneration() {
        KeyPairGenerator kpg = null;
        try {
            kpg = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        kpg.initialize(1024);
        KeyPair kp = kpg.genKeyPair();
        Key publicKey = kp.getPublic();
        Key privateKey = kp.getPrivate();
        System.out.println("Algo is :" + publicKey.getAlgorithm());

        KeyFactory fact = null;
        try {
            fact = KeyFactory.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        RSAPublicKeySpec pub = null;
        try {
            pub = fact.getKeySpec(publicKey, RSAPublicKeySpec.class);
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        RSAPrivateKeySpec priv = null;
        try {
            priv = fact.getKeySpec(privateKey, RSAPrivateKeySpec.class);
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            saveToFile("C:/public1.key", pub.getModulus(),
                    pub.getPublicExponent());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            saveToFile("C:/private1.key", priv.getModulus(),
                    priv.getPrivateExponent());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    PublicKey readKeyFromFile(String keyFileName) throws IOException {
        InputStream in = new FileInputStream(keyFileName);
        ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(
                in));

        try {
            BigInteger m = (BigInteger) oin.readObject();
            BigInteger e = (BigInteger) oin.readObject();
            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
            KeyFactory fact = KeyFactory.getInstance("RSA");
            PublicKey pubKey = fact.generatePublic(keySpec);
            return pubKey;
        } catch (Exception e) {
            throw new RuntimeException("Spurious serialisation error", e);
        } finally {
            oin.close();
        }
    }

    public byte[] rsaEncrypt(byte[] data) {
        PublicKey pubKey = null;
        try {
            pubKey = readKeyFromFile("C:/public1.key");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        byte[] cipherData = null;
        try {
            cipherData = cipher.doFinal(data);
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out
                .println("encrypted card number is :" + cipherData.toString());
        return cipherData;
    }

    PrivateKey readPriKeyFromFile(String keyFileName) throws IOException {
        InputStream in = new FileInputStream(keyFileName);
        ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(
                in));

        try {
            BigInteger m = (BigInteger) oin.readObject();
            BigInteger e = (BigInteger) oin.readObject();
            RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
            KeyFactory fact = KeyFactory.getInstance("RSA");
            PrivateKey pKey = fact.generatePrivate(keySpec);
            return pKey;
        } catch (Exception e) {
            throw new RuntimeException("Spurious serialisation error", e);
        } finally {
            oin.close();
        }
    }

    public byte[] rsaDecrypt(byte[] sampleText) {
        PrivateKey priKey = null;
        try {
            priKey = readPriKeyFromFile("C:/private1.key");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            cipher.init(Cipher.DECRYPT_MODE, priKey);
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        byte[] cipherData = null;
        try {
            cipherData = cipher.doFinal(sampleText);
            // cipherData = cipher.
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return cipherData;
    }

    public static void main(String s[]) {
        System.out
                .println("++++++++++++++++++++ Program to create the Keys+++++++++++++++++++++++++++++");
        rsaKeyGeneration();
        String sText = "HRB";
        System.out.println("Plain Text Card Number :" + sText);
        GenerateKeys keys = new GenerateKeys();
        byte[] encryptedCardNo = keys.rsaEncrypt(sText.getBytes());
        byte[] decryptedCardNo = keys.rsaDecrypt(encryptedCardNo);
        System.out.println("Decrypted card number is :"
                + decryptedCardNo.toString());

    }
}

最佳答案

这很正常,因为您使用的 toString() 方法会返回糟糕的表示形式。因此,您应该使用十六进制表示来显示加密和解密的文本。这是完成这项工作的函数:

public String byteArrayToHexString(byte[] bArray){
    StringBuffer buffer = new StringBuffer();

    for(byte b : bArray) {
      buffer.append(Integer.toHexString(b));
      buffer.append(" ");
    }

    return buffer.toString();    
}

关于java - 非对称算法使用的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8442508/

相关文章:

java - 用于 GCM 的 JAVA 中 IV 的确定性构造

c# - AES 加密 - 加密/解密添加额外字节

flutter - 解密即将到来的文本 flutter

c# - 在 Angular 中加密并在 C# 上解密

windows - SignerSignEx 用于签署 .exe 文件的示例源代码?

java - 如何克隆/复制WeakHashMap? (深拷贝)

java - 对通过values()获得的枚举常量调用函数

java - Selenium : Unable to inspect element on datepicker from chrome/firefox

java - 用Java编写线程

.net - 如何在底层 .NET 流之上创建双向加密流?