首页 > 解决方案 > RSA 密码的大输入

问题描述

我在 Android 中生成了以下公钥。

 fun createCipher(): Cipher
    {
        val posKey = posPublicKey
        posKey.publicKey.modulus

        var spec = RSAPublicKeySpec(BigInteger(posPublicKey.publicKey.modulus), BigInteger(posPublicKey.publicKey.exponent))
        var fact = KeyFactory.getInstance(KeyProperties.KEY_ALGORITHM_RSA)

        publicKey = fact.generatePublic(spec)
        var cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding")
        cipher.init(Cipher.ENCRYPT_MODE, publicKey)
        return cipher
    }

我选择的 RSA 密钥大小为 4096 字节 指数为 3 字节,模数为 512 字节

字节数组如下:

[-32, -28, -121, 32, 109, -82, 43, 115, 43, -117, 20, 35, 122, 33, -2, 23, 23, -22, 75, 0, 91, 10, -89, 48, 33, -89, 57, 1, 57, -13, 9, -127, 90, 121, -96, -94, 106, -16, -105, -112, -74, 30、-12、74、-74、104、-26、15、99、-22、-55、-75、14、-45、56、20、85、90、83、-50、68、-114 , 5, -10, -109, 79, 44, 81, 68, -98, -45, -51, -97, 71, 90, -13, -78, 118, -21, -47, 66, 104 , -83, 56, -72, -27, 45, 16, 70, 32, -76, -125, -11, 108, 126, -61, -126, 16, 6, -49, -106, - 114、18、49、121、-39、-109、115、111、-128、83、8、-110、-10、-4、51、-67、49、66、103、-76、-88 , -110, 122, 56, 29, -101, 22, 3, 117, -104, -54, -64, -71, 23, 58, 87, 37, 96, 25, -114, 38, 1, -126, 33, -91, -4, 89, -28, 10, 95, -104, -24, -38, 17, 47, -122, 24, -89, 123, 100, 12, -10, -57, -44, 45, 25, 39, -80, -101, -6, -99, -95, -5, 70, 32, 37, -57, -52, -47, -66, 85, 10, -48, 75, 4,-114、104、-7、-112、-128、4、114、77、-40、96、66、83、-54、10、111、102、-39、-63、2、-75、38 , 36, 24, 13, -51, 96, 89, -60, -40, 99, 65, 123, 52, -114, 122, 75, 32, -121, 80, -76, -11, -1 , -31, -118, -51, -21, 13, 109, 111, -102, 120, -56, 62, -19, -79, 86, -41, -81, 67, -80, -63 , 37, 35, 47, 109, -32, 47, -128, 95, -48, -53, -1, -125, -19, -9, -10, 15, -116, -50, 53, -86, -102, -24, 107, 122, -43, -125, 51, 14, 101, 67, 57, 116, 97, -40, -98, -82, -118, -83, 120, -107, -14, 19, -49, -27, 10, 25, 40, 43, -27, 31, 59, -57, 58, 33, -98, 1, -45, -118, 76, - 21, -13, -123, 67, 42, -37, -96, -32, 33, 124, 1, 44, -99, 74, 18, 32, 10, -107, -121, 86, -115 , -70, -107, 109, 17, -92, 109, -47, 60, -49, -91, 7, -125, 47, 78, 86, 81, -2, -35, 17, 124, 94, -26, -80, -84, 120, 110, 38, -55, -90, -11, 107, 73, 71, 44, 69, -58, 56, -59, 2, 94, 27, 88、29、-57、95, -99, 5, 102, -66, 118, -82, 126, 20, -104, -95, 47, -2, 77, -33, 89, -66, -92, 121, -5, 78、68、-1、-82、-95、-121、117、-29、70、11、-72、54、-99、-13、-87、9、77、-113、51、-124 , -56, -8, 126, -114, -31, 90, -125, -11, 41, -85, 74, 3, 90, -95, 85, 121, 61, 14, 116, 51, - 40, -57, -124, -69, -51, -76, -119, -80, 95, 95, 17, -34, 80, -36, 66, -51, 14, -69, -113, 35, -109, -115, -16, -3, -118, 114, -20, -81, 57, -65, 40, -8, -67, -85, 110, 50, -128, 44, -78, 93, -44, -93, 89, -76, 13, 98, -38, -55, -120, 11, 127, 84, -2, 101, 57, -121, -111, 91, -102, -118, 85, -124, -90, 91, -84, 28, 120, -28, -105, 88, -73, 6, 89, 33, 8, 9, 30, 9, -6 , 17, 25]-31、90、-125、-11、41、-85、74、3、90、-95、85、121、61、14、116、51、-40、-57、-124、-69、- 51、-76、-119、-80、95、95、17、-34、80、-36、66、-51、14、-69、-113、35、-109、-115、-16、- 3、-118、114、-20、-81、57、-65、40、-8、-67、-85、110、50、-128、44、-78、93、-44、-93、89 , -76, 13, 98, -38, -55, -120, 11, 127, 84, -2, 101, 57, -121, -111, 91, -102, -118, 85, -124, - 90、91、-84、28、120、-28、-105、88、-73、6、89、33、8、9、30、9、-6、17、25]-31、90、-125、-11、41、-85、74、3、90、-95、85、121、61、14、116、51、-40、-57、-124、-69、- 51、-76、-119、-80、95、95、17、-34、80、-36、66、-51、14、-69、-113、35、-109、-115、-16、- 3、-118、114、-20、-81、57、-65、40、-8、-67、-85、110、50、-128、44、-78、93、-44、-93、89 , -76, 13, 98, -38, -55, -120, 11, 127, 84, -2, 101, 57, -121, -111, 91, -102, -118, 85, -124, - 90、91、-84、28、120、-28、-105、88、-73、6、89、33、8、9、30、9、-6、17、25]-73、6、89、33、8、9、30、9、-6、17、25]-73、6、89、33、8、9、30、9、-6、17、25]

指数字节数组如下:

[1, 0, 1]

测试Key如下:

val stringKey = "8D-F7-5B-15-0F-2A-E5-3E-FD-44-5A-63-50-AC-62-D6-06-2D-59-5C-F1-C3-9A-DB-45-25-0D-7A-72-AE-DF-87"
val stringIV = "FA-94-FD-74-2E-AC-2C-90-79-98-AF-A3-D7-12-5D-A2"

 var aeskey = AesKeyBuilder()
            val key = (stringKey.replace("-", "")).toByteArray(Charsets.US_ASCII)

            val iv = (stringIV.replace("-", "")).toByteArray(Charsets.US_ASCII)
            aeskey.key = key
            aeskey.iv = iv

val encryptedKey = cipher.doFinal(aesKey.Key)

我要加密的项目是 64 字节。使用这个公钥。

但是,我收到以下错误:

Process: com.touchsides.rewards.debug, PID: 19470
com.android.org.bouncycastle.crypto.DataLengthException: input too large for RSA cipher.
    at com.android.org.bouncycastle.crypto.engines.RSACoreEngine.convertInput(RSACoreEngine.java:115)
    at com.android.org.bouncycastle.crypto.engines.RSABlindedEngine.processBlock(RSABlindedEngine.java:95)
    at com.android.org.bouncycastle.crypto.encodings.OAEPEncoding.encodeBlock(OAEPEncoding.java:199)
    at com.android.org.bouncycastle.crypto.encodings.OAEPEncoding.processBlock(OAEPEncoding.java:131)

我相信模数足够大,可以加密这个字节数组。

标签: javaandroidrsapublic-key-encryption

解决方案


您会收到com.android.org.bouncycastle.crypto.DataLengthException错误消息,因为 RSA 密钥是使用负模数创建的。所以它甚至不能用于加密一个字节。

BigInteger默认构造函数使用提供的字节数组有效负载的最高有效位作为数字的符号位。因此,您必须使用另一个构造函数明确指定您想要一个正数,其中第一个参数是符号指示符:

BigInteger(1, posPublicKey.publicKey.modulus), BigInteger(1, posPublicKey.publicKey.exponent)

还有一种 C# 方法可以在字节数组前面添加一个零字节(因此符号位将始终为零):

BigInteger(byteArrayOf(0) + posPublicKey.publicKey.modulus), BigInteger(byteArrayOf(0) + posPublicKey.publicKey.exponent)

最后,如果您已经BigInteger创建了错误的方式,则可以转换它:

var modulus = BigInteger(posPublicKey.publicKey.modulus)
if (modulus.compareTo(BigInteger.ZERO) < 0)
    modulus = modulus.add(BigInteger.ONE.shiftLeft(4096))

另请查看此问题的答案和答案。


推荐阅读