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

发布于 2024-09-03 05:36:39 字数 1878 浏览 3 评论 0原文

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

我试图加密私钥的模数和指数,但以下测试代码引发异常,因为字节数组比 RSA 块允许的最大值大 1 个字节:

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 块允许的最大值,那么为什么会出现异常呢?以及如何修复它?

编辑:如果我用 1023(而不是 1024)初始化密钥对生成器,它可以工作,但是 RSA 密钥大小不是通常的 1024 吗?

I know its not the usual thing to do. But the specification I'm implementing is discribed this way, and I cannot run out.

I was trying to encrypt the modulus and exponent of the private key, but the following test code raises an exception because the byte array is 1 byte larger then the maximum allowed by RSA block:

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. its just a test, i would never encrypt the private key with its pair public key)

The byte array is 128 bytes, the exactly maximum allowed by a RSA block, so why the exception? And how to fix it?

EDIT: if I initilize the key pair generator with 1023 (instead of 1024) it works, but isn't the usual for RSA key size 1024?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

时间你老了 2024-09-10 05:36:39

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

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

编辑: 正如 GregS 在评论中指出的那样,你不能确保要加密的密钥的私有指数小于要用于加密的密钥的模数。我认为大约 25% 的情况下情况并非如此。所以请改用下面的方法。

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

First: Someone has written this specification. Check with them instead of asking us. They have some reason for writing this requirement and you need to know what it is. When facing an unclear requirement the worst thing you can do is to begin guessing - especially when handling cryptography.

Second: in your test-code you are encrypting the private key modulus. The modulus is not secret in the RSA crypto-system, so there should be no need to encrypt this. You are not attempting to encrypt the private exponent (which is the actual secret part). The private exponent is always smaller than the modulus, so you should be able to encrypt it using the raw RSA operation (if you make sure to remove the prepended zero). This should be secure (translation: I do not see any obvious attacks considering it for 30 seconds) - if non-standard.

EDIT: As GregS points out in the comments, you cannot be sure that the private exponent of the key you want to encrypt is smaller than the modulus of the key you want to use to encrypt with. I think approximately 25% of the time this will not be the case. So use the method below instead.

An even better way to do it (which is completely standard and which I suspect is what the specification-writers actually intends) would be to encrypt the private key using the usual hybrid approach: Generate a symmetric key, use it to encrypt the private key (here you can use a standard serialized format without having to worry about the length), encrypt the symmetric key with the other public key (using RSA/PKCS#1) and transmit the two encryptions to the recipient who performs the opposite steps.

记忆消瘦 2024-09-10 05:36:39

您确定需要这样做吗?大多数人使用 RSA 密钥加密对称密钥,但在 RSA 内部加密 RSA 不会给您带来任何好处。

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

  (key_size/8) - 11 bytes

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

Are you sure you need to do this? Most people encrypt symmetric keys with RSA key but encrypting RSA inside RSA doesn't buy you anything.

The maximum size of clear text can be encrypted by RSA is

  (key_size/8) - 11 bytes

So you can only encrypt 117 bytes for 1024-bit key. You need to use a much larger key to encrypt a smaller key.

一个人的夜不怕黑 2024-09-10 05:36:39

如果您绝对想使用自己的加密协议(这通常不是一个好主意),那么您可以将公钥(即模数 N 和公钥 e)保留为明文,并简单地加密因子 N 之一。对于 1024 位模数,因子大约为 512 位,您应该不会遇到加密问题。知道其中一个因素和公钥就足以确定私钥的其余部分。

If you absolutely want to use your own crypto protocol (which usually is not a good idea) then you could keep the public key (i.e. the modulus N and the public key e) as plaintext and simply encrypt one of the factors N. Since the facotors are about 512 bits for a a 1024 bit modulus, you should not have a problem with the encrytion. Knowing one of the factors and the public key is enough to determine the remainder of the private key.

甚是思念 2024-09-10 05:36:39

PKCS#1 方法添加 11 个字节的校验和和填充,因此最大纯文本大小将为 117 个字节。请参阅 RSA 块数据过多失败。什么是 PKCS#7?

The PKCS#1 method adds 11 bytes of checksums and padding, so your maximum plain-text size will be 117 bytes. See Too much data for RSA block fail. What is PKCS#7?

月朦胧 2024-09-10 05:36:39

RSA 中可以加密的数据量等于密钥大小 - 11 字节。如果您想存储更多数据,则应从 1024 开始增加密钥大小。

The amount of data you can encrypt in RSA is equal to the key size - 11 bytes. If you want to store more data, you should increase your key size from 1024.

东北女汉子 2024-09-10 05:36:39

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

抱歉打扰你们了(我试图删除这个问题,但现在删除不了)。

The answer I was looking was (almost hidden) in the project's specification. Its to encrypt the rsa key by parts, and concatenate the parts. The same to decrypt (of course the size will need to be a default size known by encryptor and decryptor). This way I can use RSA without any symmetric key (not that I agree that this is the best encryption method).

Sorry trouble you guys (I tried to delete this question, but it cannot be deleted now).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文