在Java中使用模数和指数进行RSA加密 [英] RSA Encryption using modulus and exponent in Java

查看:959
本文介绍了在Java中使用模数和指数进行RSA加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在Java上进行RSA加密,因此必须使用私有模数和公共模数进行加密。我目前有以下内容:

I'm currently doing RSA encryption on Java and I have to use private and public modulus for the encryption. I currently Have the following:

private void createPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
        String publicModulus = "d2c34017ef94f8ab6696dae66e3c0d1ad186bbd9ce4461b68d7cd017c15bda174045bfef36fbf048" +
                "73cfd6d09e3806af3949f99c3e09d6d3c37f6398d8c63f9a3e39b78a187809822e8bcf912f4c44a8" +
                "92fe6a65a477ddea9582738317317286a2610ba30b6b090c3b8c61ffb64207229b3f01afe928a960" +
                "c5a44c24b26f5f91";

        BigInteger keyInt = new BigInteger(publicModulus, 16);
        BigInteger exponentInt = new BigInteger("10001", 16);
        RSAPublicKeySpec keySpeck = new RSAPublicKeySpec(keyInt, exponentInt);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        publicKey = keyFactory.generatePublic(keySpeck);

    }

private void createPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
        String privateModulus = "6c97ab6369cf00dd174bacd7c37e6f661d04e5af10670d4d88d30148ec188e63227b8dac0c517cf9" +
                "67aa73cd23684c9165dc269f091bfab33b6c5c7db95b54130e348255c30aaaac1c7f09ef701e0d6f" +
                "6dc142d2e4ed78466cc104e28d50be7adf3863afc021dbdd8b5f0b968b7cd965242c7d8d4b32ee84" +
                "0fac3cad134344c1";
        BigInteger privateModulusInt = new BigInteger(privateModulus, 16);
        BigInteger exponentInt = new BigInteger("10001", 16);
        RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(privateModulusInt, exponentInt);
        KeyFactory factory = KeyFactory.getInstance("RSA");
        privateKey = factory.generatePrivate(privateKeySpec);
    }

在主要方法中,我有以下内容:

In the main method I have the following:

        createPrivateKey();
        createPublicKey();

        String data = "12";

        Cipher cipher1 = Cipher.getInstance("RSA/ECB/NoPadding");
        cipher1.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedData = cipher1.doFinal(data.getBytes());

        Cipher cipher2 = Cipher.getInstance("RSA/ECB/NoPadding");
        cipher2.init(Cipher.DECRYPT_MODE,privateKey);
        byte[] decryptedData = cipher2.doFinal(encryptedData);
        System.out.println(new String(decryptedData));

在控制台中,我得到以下信息: ..7 p;%kV。 9y xa ɼ{而不是 12 如果我使 String data = 12345; ,然后得到: javax.crypto.BadPaddingException:消息大于模数

In the console I get the following: ���.7���p;%kV�9y���xa�ɼ{ and not "12" If I make the String data = "12345";, I then get: javax.crypto.BadPaddingException: Message is larger than modulus

首先为什么要加密和解密不起作用?为什么我不找回 12 。其次,为什么我的数据不能超过2个字符?

Firstly why is the encryption and decryption not working? Why am I not getting back "12". Secondly why can I not have data be greater than 2 characters?

请注意,我正在使用以下网站

Note I'm using the following website to get the modulus and exponent values.

推荐答案

创建私钥时出错。您提供的是公用指数而不是私有指数,(提供了@ dave_thomsom_085注释)是私有指数而不是模数

There is an error creating the private key. You are providing the public exponent instead of private and (as commented @dave_thomsom_085) private exponent instead of modulus

更改 createPrivateKey()

private static PrivateKey createPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
        String publicModulus = "d2c34017ef94f8ab6696dae66e3c0d1ad186bbd9ce4461b68d7cd017c15bda174045bfef36fbf048" +
                "73cfd6d09e3806af3949f99c3e09d6d3c37f6398d8c63f9a3e39b78a187809822e8bcf912f4c44a8" +
                "92fe6a65a477ddea9582738317317286a2610ba30b6b090c3b8c61ffb64207229b3f01afe928a960" +
                "c5a44c24b26f5f91";
        String privateExponent = "6c97ab6369cf00dd174bacd7c37e6f661d04e5af10670d4d88d30148ec188e63227b8dac0c517cf9" +
                "67aa73cd23684c9165dc269f091bfab33b6c5c7db95b54130e348255c30aaaac1c7f09ef701e0d6f" +
                "6dc142d2e4ed78466cc104e28d50be7adf3863afc021dbdd8b5f0b968b7cd965242c7d8d4b32ee84" +
                "0fac3cad134344c1";
        BigInteger privateExponenInt = new BigInteger(privateExponent, 16);
        BigInteger keyInt = new BigInteger(publicModulus, 16);
        RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(keyInt, privateExponenInt);
        KeyFactory factory = KeyFactory.getInstance("RSA");
        return factory.generatePrivate(privateKeySpec);
    }

出于安全原因,也不应使用未经填充的原始RSA。使用 RSA / ECB / PKCS1Padding 或新的OAEP填充 RSA / ECB / OAEPWithSHA1AndMGF1Padding

Also you should not use raw RSA without padding for security reasons. Use RSA/ECB/PKCS1Padding or the new OAEP padding RSA/ECB/OAEPWithSHA1AndMGF1Padding

根据此答案,您可以使用 PKCS1Padding进行加密数据最多比键大小小11个字节。 并使用OAEP 必须小于密钥模数的大小– 41

According to this answer you can encrypt with PKCS1Padding data up to 11 bytes less than the key size. and using OAEP it must be less than the size of the key modulus – 41

然后,使用您的1024位密钥:

Then, using your 1024 bits key:


  • PKCS1:(1024位/ 8)-11 = 117字节

  • OAEP:(1024位/ 8)-42 = 86字节

  • PKCS1: (1024 bits / 8) - 11 = 117 bytes
  • OAEP: (1024 bits / 8) - 42 = 86 bytes

也建议使用CRT而不是直接使用私有指数

Also is recommended to use CRT instead of private exponent directly

RSAPrivateCrtKeySpec privateKeySpec = 
    new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP, primeQ, primeExpP, primeExpQ, crtCoefficient);

这篇关于在Java中使用模数和指数进行RSA加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆