java - 超过 110 字节的大字符串的 SealedObject 大小错误

标签 java encryption rsa key-pair

我以rsa加密和解密为例。如果消息大于 110 字节,我无法解密。但错误说;数据不得超过 117 字节。为什么7字节不能用?

我的类(class):

public class RSAEx {

    static Cipher cipher;
    static KeyPairGenerator keyPairGenerator;
    static KeyPair keyPair;
    static String message = "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";

    public static void main(String[] ars) throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, NoSuchPaddingException, IOException, BadPaddingException {
        keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPair = keyPairGenerator.generateKeyPair();
        cipher = Cipher.getInstance("RSA");
        decryptIt(encryptIt());
    }

    static byte[] encryptIt() throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException {
        cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
        SealedObject encryptedMessage = new SealedObject(message, cipher);
        System.out.println("Encrypt Alg : "+encryptedMessage.getAlgorithm());
        System.out.println("Encrypted Msg : ");
        for (int i = 0; i < keyPair.getPrivate().getEncoded().length; i++){
            System.out.print(keyPair.getPrivate().getEncoded()[i]);
        }
        System.out.print("\n");

        return cipher.doFinal(message.getBytes());
    }

    static void decryptIt(byte[] encryptedMessage) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
        cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
        System.out.println("Decrypted Msg : "+new String(cipher.doFinal(encryptedMessage)));
    }
}

错误:

Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:344)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
    at javax.crypto.Cipher.doFinal(Cipher.java:2165)
    at javax.crypto.SealedObject.<init>(SealedObject.java:170)
    at com.mimcrea.metronic_ui_android.RSAEx.encryptIt(RSAEx.java:35)
    at com.mimcrea.metronic_ui_android.RSAEx.main(RSAEx.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)

最佳答案

您可能使用的是旧版本的 java,RSA key 大小为 1024?在我的计算机上,java 8 it 2048 key 大小最大为 245 字节。

它是 key 大小/8 - 填充,即 11 字节。所以在这里我得到了异常(exception):

线程“main”javax.crypto.IllegalBlockSizeException中出现异常:数据不得超过245字节

2048/8 - 11 = 245 字节

对于您来说, key 大小为 1024 -> 1024/8 - 11 = 117

问题在于您执行密封对象的代码。由于密码为 7 个字节,该密封对象可能会带来一些开销。如果您尝试这样的代码:

static Cipher cipher;
    static KeyPairGenerator keyPairGenerator;
    static KeyPair keyPair;
    static String message = "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";

    public static void main(String[] ars) throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, NoSuchPaddingException, IOException, BadPaddingException {
        keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPair = keyPairGenerator.generateKeyPair();
        cipher = Cipher.getInstance("RSA");
        decryptIt(encryptIt());
    }

    static byte[] encryptIt() throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException {
        cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
        System.out.println("Size:"+message.getBytes().length);
        return cipher.doFinal(message.getBytes());
    }

    static void decryptIt(byte[] encryptedMessage) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException {
        cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
        System.out.println("Decrypted Msg : "+new String(cipher.doFinal(encryptedMessage)));
    }

无需创建 SealedObject(因为您无论如何都不使用它),您将能够精确地加密和解密 117 个字节。

关于java - 超过 110 字节的大字符串的 SealedObject 大小错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49920742/

相关文章:

ssl - SSL 加密的重要性

javascript - 如何在数据库中存储 CryptoJS 加密密码

encryption - RSA 私钥格式

ios - 如何使用 Linux openssl 为 iOS 生成 CSR?

java - 如何监听JTable表头的鼠标点击?

java - JNA:如何定义具有自定义位大小字段的结构?

java - 随机访问文件和 UTF 8 行

java - gson 抛出 MalformedJsonException

encryption - 如何生成一对非对称加密 key ?

c# - 无法验证在 C# 中创建的签名