当前位置: 首页 > 知识库问答 >
问题:

用RSA和另一个密钥加密消息

宰父深
2023-03-14

第二,客户端向服务器端发送公钥。

服务器生成对称AES密钥。

4T:服务器用他的AES密钥加密他想要发送给客户端的文本。

public class Test {

    private static SecretKey secretKey;
    private static KeyPair keyPair;
    private static final String STRINGTOENCRYPT = "This is a test";
    private static String stringEncripted;
    private static String keyEncripted;
    public static final byte[] IV_PARAM = {0x00, 0x01, 0x02, 0x03,
            0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0A, 0x0B,
            0x0C, 0x0D, 0x0E, 0x0F};


    public static void main(String[] args) {
        generateKeys();
    }

    private static void generateKeys() {

        secretKey = generateSecretKey(128);
        keyPair = generateKeyPair(512);
        stringEncripted = encriptString(STRINGTOENCRYPT);
        keyEncripted = encriptKey(keyPair.getPublic());

        decryptString();

    }

    private static void decryptString() {
        Cipher cipher = null;
        Key keyDecrypted = null;
        try {
            cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.UNWRAP_MODE, keyPair.getPrivate());
            keyDecrypted = cipher.unwrap(keyEncripted.getBytes(), "AES", Cipher.SECRET_KEY);

            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(IV_PARAM);
            cipher.init(Cipher.DECRYPT_MODE, keyDecrypted, iv);
            byte[] stringDecryptedBytes = cipher.doFinal(stringEncripted.getBytes());
            String stringDecrypted = new String(stringDecryptedBytes);

            System.out.println(stringDecrypted);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private static KeyPair generateKeyPair(int lenght) {
        KeyPair keyPublicAndPrivate = null;

        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(lenght);
            keyPublicAndPrivate = keyGen.genKeyPair();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return keyPublicAndPrivate;

    }

    private static SecretKey generateSecretKey(int lenght) {


        SecretKey sKey = null;
        if ((lenght == 128) || (lenght == 192) || (lenght == 256)) {
            try {
                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                kgen.init(lenght);
                sKey = kgen.generateKey();
            } catch (NoSuchAlgorithmException ex) {
                ex.printStackTrace();
            }
        }
        return sKey;

    }

    private static String encriptString(String stringtoencrypt) {

        byte[] stringtoencryptBytes = stringtoencrypt.getBytes();
        Cipher cipher = null;

        String stringEncrypted = null;
        try {
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(IV_PARAM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

            byte[] stringEncryptedBytes = cipher.doFinal(stringtoencryptBytes);
            stringEncrypted = new String(cipher.doFinal(stringtoencryptBytes), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }


        return stringEncrypted;
    }


    private static String encriptKey(PublicKey aPublic) {
        String keyEncryptedString = null;
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.WRAP_MODE, aPublic);
            byte[] keyEncriptedBytes = cipher.wrap(secretKey);
            keyEncryptedString = new String(keyEncriptedBytes, "UTF-8");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return keyEncryptedString;
    }

}

共有1个答案

奚无尘
2023-03-14

问题是,您不能仅仅假设RSA或AES加密会产生表示字符串的字节。当您使用new string生成字符串时,它将以静默方式删除所有不代表字符的字节。如果希望获得更多的控制权并引发异常(本应是默认值),可以使用charsetdecoder

问题是,当您重新转换为字节时,某些字节可能会丢失。这意味着这个数字可能会小得多,这会以这样或那样的方式引发异常,因为unwrap的输入现在太小了。

以下是一些更改,说明如何使其工作。我只是注释掉了你的代码,这样你就可以比较了。

import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class Test {

    private static SecretKey secretKey;
    private static KeyPair keyPair;
    private static final String STRINGTOENCRYPT = "This is a test";
    private static String stringEncripted;
    private static byte[] ct;
    private static String keyEncripted;
    private static byte[] wrapped;
    public static final byte[] IV_PARAM = {0x00, 0x01, 0x02, 0x03,
            0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0A, 0x0B,
            0x0C, 0x0D, 0x0E, 0x0F};


    public static void main(String[] args) {
        generateKeys();
    }

    private static void generateKeys() {

        secretKey = generateSecretKey(128);
        keyPair = generateKeyPair(512);
        stringEncripted = encriptString(STRINGTOENCRYPT);
        keyEncripted = encriptKey(keyPair.getPublic());

        decryptString();

    }

    private static void decryptString() {
        Cipher cipher = null;
        Key keyDecrypted = null;
        try {
            cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.UNWRAP_MODE, keyPair.getPrivate());
            // keyDecrypted = cipher.unwrap(keyEncripted.getBytes(), "AES", Cipher.SECRET_KEY);
            keyDecrypted = cipher.unwrap(wrapped, "AES", Cipher.SECRET_KEY);

            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(IV_PARAM);
            cipher.init(Cipher.DECRYPT_MODE, keyDecrypted, iv);
            byte[] stringDecryptedBytes = cipher.doFinal(ct);
            String stringDecrypted = new String(stringDecryptedBytes);

            System.out.println(stringDecrypted);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private static KeyPair generateKeyPair(int lenght) {
        KeyPair keyPublicAndPrivate = null;

        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(lenght);
            keyPublicAndPrivate = keyGen.genKeyPair();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return keyPublicAndPrivate;

    }

    private static SecretKey generateSecretKey(int lenght) {


        SecretKey sKey = null;
        if ((lenght == 128) || (lenght == 192) || (lenght == 256)) {
            try {
                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                kgen.init(lenght);
                sKey = kgen.generateKey();
            } catch (NoSuchAlgorithmException ex) {
                ex.printStackTrace();
            }
        }
        return sKey;

    }

    private static String encriptString(String stringtoencrypt) {

        byte[] stringtoencryptBytes = stringtoencrypt.getBytes();
        Cipher cipher = null;

        String stringEncrypted = null;
        try {
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(IV_PARAM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

            // byte[] stringEncryptedBytes = cipher.doFinal(stringtoencryptBytes);
            ct = cipher.doFinal(stringtoencryptBytes);
            stringEncrypted = new String(cipher.doFinal(stringtoencryptBytes), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }


        return stringEncrypted;
    }


    private static String encriptKey(PublicKey aPublic) {
        String keyEncryptedString = null;
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.WRAP_MODE, aPublic);
//            byte[] keyEncriptedBytes = cipher.wrap(secretKey);
//            keyEncryptedString = new String(keyEncriptedBytes, "UTF-8");
            wrapped = cipher.wrap(secretKey);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return keyEncryptedString;
    }

}
 类似资料:
  • 问题内容: 我正在编写一个用于传输文件的小型应用程序,或多或少地将其作为一种学习更多编程加密基础的方法。这个想法是生成一个RSA密钥对,交换公共密钥,并发送AES iv和密钥以进一步解密。我想用接收者的RSA公钥加密AES密钥,如下所示: 然后,我将密钥值写给接收器,并按如下方式解密: 在控制台的另一端,我将其作为输出: 此外,如果我创建一个大小为16的字节数组,并将cipher.doFinal(

  • 我使用Delphi XE和Lockbox3.5,我想加密一个字符串,该字符串具有支付网关提供的公钥,需要操作,公钥类似于:------开始公钥------这里的职员------结束公钥------我无法使RSA编解码器读取该公钥,我的代码如下: 编解码器cdcRA链接到CryptoLibrary,密码为(RSA公钥加密系统*),链接模式为空,但此代码失败,并出现内存不足错误。谢谢你的提示。。 演示

  • 这是我的密码 抱歉,如果我的代码一团糟。

  • 我试图通过RSA加密字符串。我也有java样本,但我不能正确地将其转换为c#。 RSA示例: 这是我在c#中生成的代码,但我的c#代码结果与javaCode结果不同。我的代码怎么了?

  • 我的进程: 1。生成对称密钥 2。使用对称密钥 3加密数据。使用RSA 4加密对称密钥。发送加密密钥和数据 5。使用RSA 6解密加密的对称密钥。使用对称密钥 7解密数据。已完成

  • 并且我将这个函数称为用RSA公钥加密DSA密钥的函数: