代码之家  ›  专栏  ›  技术社区  ›  Student

如何使用另一个RSAKey加密RSAKey?

  •  0
  • Student  · 技术社区  · 16 年前

    我知道这不是常做的事。但是我正在实现的规范是这样描述的,我不能用完。

    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    
    import javax.crypto.Cipher;
    
    import org.apache.commons.lang.ArrayUtils;
    
    public class TEST {
    
        public static KeyPair generateKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException {
     KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
     keyPairGenerator.initialize(1024);
     return keyPairGenerator.generateKeyPair();
        }
    
        public static void main(String[] args) throws Exception {
    
     KeyPair keyPair = generateKeyPair();
     RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
    
     System.out.println("Priv modulus len = " + privateKey.getModulus().bitLength());
     System.out.println("Priv exponent len = " + privateKey.getPrivateExponent().bitLength());
     System.out.println("Priv modulus toByteArray len = " + privateKey.getModulus().toByteArray().length);
    
     byte[] byteArray = privateKey.getModulus().toByteArray();
     // the byte at index 0 have no value (in every generation it is always zero)
     byteArray = ArrayUtils.subarray(byteArray, 1, byteArray.length);
    
     System.out.println("byteArray size: " + byteArray.length);
    
     RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
     Cipher cipher = Cipher.getInstance("RSA", "BC");
     cipher.init(Cipher.ENCRYPT_MODE, publicKey);
     byte[] encryptedBytes = cipher.doFinal(byteArray);
    
     System.out.println("Success!");
        }
    
    }
    

    (obs。这只是一个测试,我永远不会用它的公钥对私钥进行加密)

    字节数组是128字节,正好是RSA块允许的最大值,那么为什么会出现异常呢?如何修复?

    6 回复  |  直到 16 年前
        1
  •  2
  •   Rasmus Faber    16 年前

    第一:有人写了这个规范。去问问他们,而不是问我们。他们写这个要求是有原因的,你需要知道它是什么。当你面对一个不明确的需求时,你能做的最糟糕的事情就是开始猜测——尤其是在处理密码的时候。

    第二:在测试代码中,您正在加密私钥模数。在RSA密码系统中,模不是秘密的,因此不需要对其进行加密。您没有试图加密私有指数(这是实际的秘密部分)。私有指数总是小于模,因此您应该能够使用原始RSA操作对其进行加密(如果您确保删除前面的零)。这应该是安全的(翻译:我没有看到任何明显的攻击考虑30秒)-如果非标准的。

    正如GregS在注释中指出的,您不能确定要加密的密钥的私有指数是否小于要用于加密的密钥的模数。我想大概有25%的时间

    一个更好的方法(这是完全标准的,我怀疑这是规范编写者真正想要的)是使用通常的混合方法来加密私钥:生成一个对称密钥,使用它来加密私钥(这里您可以使用标准的序列化格式,而不必担心长度),用另一个公钥(使用RSA/PKCS#1)加密对称密钥,并将这两个加密传输给执行相反步骤的接收方。

        2
  •  1
  •   ZZ Coder    16 年前

    你确定要这么做吗?大多数人用RSA密钥加密对称密钥,但在RSA内部加密RSA并不能给你带来任何好处。

    RSA可以加密的明文的最大大小是

      (key_size/8) - 11 bytes
    

    因此,对于1024位密钥,只能加密117个字节。您需要使用更大的密钥来加密更小的密钥。

        3
  •  1
  •   Nonce    16 年前

        4
  •  0
  •   Community Mohan Dere    9 年前

    PKCS#1方法添加11字节的校验和和填充,因此您的最大纯文本大小将是117字节。看到了吗 Too much data for RSA block fail. What is PKCS#7?

        5
  •  0
  •   Marcus Adams    16 年前

        6
  •  0
  •   Tom Brito    16 年前

    我所寻找的答案(几乎隐藏在)项目规范中。其目的是对rsa密钥进行部分加密,并将部分连接起来。解密也是一样(当然大小需要是加密和解密程序已知的默认大小)。这样我就可以在没有任何对称密钥的情况下使用RSA(我并不认为这是最好的加密方法)。