You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中RSA/OAEP加密64字节数据遇输入过大错误求助

解决RSA OAEP加密时的"input too large"异常

我看到你遇到的问题了,虽然4096位RSA理论上应该能轻松加密64字节的数据,但你的代码里有两个关键问题导致了这个异常,下面一步步帮你解决:

问题1:RSA公钥生成时的BigInteger构造错误

你的模数字节数组第一个元素是-32(即十六进制的0xE0),这个字节的最高位是1。当你直接用BigInteger(posPublicKey.publicKey.modulus)构造BigInteger时,Java会把这个字节数组当成有符号整数的补码,生成一个负数的BigInteger。但RSA的模数必须是正整数,这会导致你生成的公钥无效,最终在加密时触发误导性的"input too large"错误。

修正方法是使用BigInteger的带符号参数的构造函数,明确告诉它要把字节数组解析为正整数:

var spec = RSAPublicKeySpec(BigInteger(1, posPublicKey.publicKey.modulus), BigInteger(1, posPublicKey.publicKey.exponent))

(注意指数的字节数组[1,0,1]最高位是0,不会有问题,但为了统一和安全,最好也加上1作为第一个参数)

问题2:AES密钥的错误转换

你的代码里把十六进制字符串转成ASCII字节数组:

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

比如stringKey去掉-后是64个十六进制字符,每个字符转成ASCII字节(比如'8'是0x38,'D'是0x44),这样得到的是64字节的数组,但实际上AES-256密钥应该是32字节的二进制数据(由64个十六进制字符解析而来)。虽然4096位RSA OAEP支持的最大明文长度远大于64字节,但这个错误的密钥转换是不必要的,而且可能和第一个问题叠加导致异常。

修正方法是把十六进制字符串解析为二进制字节数组:

fun hexStringToByteArray(hex: String): ByteArray {
    val len = hex.length
    val data = ByteArray(len / 2)
    var i = 0
    while (i < len) {
        data[i / 2] = ((Character.digit(hex[i], 16) shl 4) + Character.digit(hex[i+1], 16)).toByte()
        i += 2
    }
    return data
}

// 然后替换原来的key和iv转换代码:
val key = hexStringToByteArray(stringKey.replace("-", ""))
val iv = hexStringToByteArray(stringIV.replace("-", ""))

修正后的完整代码片段

fun hexStringToByteArray(hex: String): ByteArray {
    val len = hex.length
    val data = ByteArray(len / 2)
    var i = 0
    while (i < len) {
        data[i / 2] = ((Character.digit(hex[i], 16) shl 4) + Character.digit(hex[i+1], 16)).toByte()
        i += 2
    }
    return data
}

fun createCipher(): Cipher {
    val posKey = posPublicKey
    // 修正:用BigInteger(1, ...)构造正整数模数和指数
    val modulus = BigInteger(1, posPublicKey.publicKey.modulus)
    val exponent = BigInteger(1, posPublicKey.publicKey.exponent)
    var spec = RSAPublicKeySpec(modulus, exponent)
    var fact = KeyFactory.getInstance(KeyProperties.KEY_ALGORITHM_RSA)
    val publicKey = fact.generatePublic(spec)
    var cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding")
    cipher.init(Cipher.ENCRYPT_MODE, publicKey)
    return cipher
}

// 加密部分的修正
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 = hexStringToByteArray(stringKey.replace("-", ""))
val iv = hexStringToByteArray(stringIV.replace("-", ""))
aeskey.key = key
aeskey.iv = iv
val encryptedKey = cipher.doFinal(aeskey.key)

补充说明

4096位RSA使用OAEPWithSHA-256AndMGF1Padding时,最大明文长度计算公式是:
(密钥长度 / 8) - 2 * 哈希长度 - 2
代入数值:512 - 2*32 -2 = 446字节,所以即使你加密64字节的数据(虽然这是错误的密钥转换结果),理论上也是支持的,但公钥无效的问题才是触发异常的根本原因。

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:46:55