无法使用我的私钥从 API 解码字符串

Cant decode string from API using my Private Key

我正在尝试从 API

获取 accessToken

我生成一个 public/private 密钥对,我发送 public 密钥,API returns 一个加密的 accessToken,我应该用我的私钥解密(基本看起来)

我相信我做的一切都是正确的,但是当我从 API 解密数据时,我得到这样的结果:

�_Q�� w�����f�]&Af3��n� ������L�迟��T�0E2K�g���De��D�q2]�0;�0���_@�T6��jz;�:fdZN�䧉d�~��N� �3��$.)���%�u��5�wS{W`����u��M8ⵌ��oQ��@���S�� Z��,i��0����S3ue�����������g>��u��oV�����N̂Y�ׂ���Ѕ�S�<���޳%�L\I���z��}�=��x^�5�R��@�Y��2F��NCWS��}�ȏ�O����   ����E��ڰ�W�F*K �t��¥d��T�0�!j؞y�G�1�����5��Iޖ7ɛ��   o�U�����Ú�r�϶��Ӂ�b5�$��0�oȸ����jh�ÝǧeyJraWQiOiJiNjRjNjZmZS00ZWY5LTExZTktODY0Ny1kNjYzYmQ4NzNkOTMiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJzdWIiOiI4MjE1NDliNi1iNzk1LTQwOGMtYjg4MS03MTA2OWY4NmE3OGMiLCJpc3MiOiJpRm9vZCIsInRlbmFudElkIjoiSUZPIiwidHlwZSI6ImFjY2Vzc190b2tlbiIsImV4cCI6MTU5OTg2MjU4OSwiaWF0IjoxNTk5ODU1Mzg5fQ.Qhf2pJctrhFBGGxAcat4xc0oVhytE-cffkoLt8kQZ7KcsWQzygYX2t00DGSSEepBUNUN3yl9Jr0MhRI6K-7sfgD-W8v4M8rE-kcbp4O0nZjLlWzNuZ8s6g5OPw9oIpaqORnNaPT9UpYDOqw-Zvr4E0syN46AwpE6QpZR2lWxr2JW665NoWXoPXoSiMWhwSTMi-IT-ZMDg-tVknC8Oikhu9tnIpJWTI7VKX5iG-93glJTZRkFGTAxV2hPTv9RAeRnGUhBCa2CCJXn8Y6phGd2qpECbQvc7LK04pHDqElvp5ofaqMM87bZKCuFDaqm2jIXylIxWgtkK7GtVrp9oZOf3A

我应该什么时候得到这个

eyJraWQiOiJiNjRjNjZmZS00ZWY5LTExZTktODY0Ny1kNjYzYmQ4NzNkOTMiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJzdWIiOiI4MjE1NDliNi1iNzk1LTQwOGMtYjg4MS03MTA2OWY4NmE3OGMiLCJpc3MiOiJpRm9vZCIsInRlbmFudElkIjoiSUZPIiwidHlwZSI6ImFjY2Vzc190b2tlbiIsImV4cCI6MTU5OTg2MjU4OSwiaWF0IjoxNTk5ODU1Mzg5fQ.Qhf2pJctrhFBGGxAcat4xc0oVhytE-cffkoLt8kQZ7KcsWQzygYX2t00DGSSEepBUNUN3yl9Jr0MhRI6K-7sfgD-W8v4M8rE-kcbp4O0nZjLlWzNuZ8s6g5OPw9oIpaqORnNaPT9UpYDOqw-Zvr4E0syN46AwpE6QpZR2lWxr2JW665NoWXoPXoSiMWhwSTMi-IT-ZMDg-tVknC8Oikhu9tnIpJWTI7VKX5iG-93glJTZRkFGTAxV2hPTv9RAeRnGUhBCa2CCJXn8Y6phGd2qpECbQvc7LK04pHDqElvp5ofaqMM87bZKCuFDaqm2jIXylIxWgtkK7GtVrp9oZOf3A

奇怪的是,我进行了单元测试以尝试重现该问题,但随后一切正常

下面是我的代码

class AuthenticationQrCodeViewModel @Inject constructor(
    override val viewState: AuthenticationQrCodeViewState,
    private val initializeAuth: InitializeAuthUseCase,
    private val fetchAuthToken: FetchAuthTokenUseCase,
    private val setupAccountUseCase: SetupAccountUseCase,
    private val cryptographyService: CryptographyService
) :
    BaseViewModel<AuthenticationQrCodeViewState, AuthenticationQrCodeViewAction>() {

    init {
        viewModelScope.launch {
            var jobForPolling: Job? = null
            while (true) {
                initializeAuth().onSuccess { authModel ->
                    viewState.action.value = AuthenticationQrCodeViewState.Action.GenerateQrCode(authModel.authId)
                    jobForPolling?.apply { cancel() }
                    jobForPolling = pollForAuthToken(authModel)
                }
                delay(QR_CODE_GENERATION_DELAY)
            }
        }
    }

    private fun pollForAuthToken(authModel: AuthModel): Job {
        return viewModelScope.launch {
            fetchAuthToken(authModel.authId).collect { result ->
                result.onSuccess {
                    if (it.accessToken.isEmpty().not() || it.refreshToken.isEmpty().not()) {
                        val jwtToken = JwtToken(
                            accessToken = cryptographyService.decrypt(
                                Base64.decode(it.accessToken, Base64.DEFAULT),
                                authModel.keyPair.private

                            ),
                            refreshToken = cryptographyService.decrypt(
                                Base64.decode(it.refreshToken, Base64.DEFAULT),
                                authModel.keyPair.private
                            ),
                            accountId = "",
                            externalId = null
                        )
                        setupAccountUseCase(jwtToken, LoginTypeModel.LOGIN)
                        viewState.action.value = AuthenticationQrCodeViewState.Action.GoToHome
                        this.cancel()
                    }
                }
            }
        }
    }
} 
class InitializeAuth @Inject constructor(
    private val authRepository: AuthRepository
) : InitializeAuthUseCase {
    override suspend fun invoke(): Result<AuthModel, ResultError> {
        val generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA)
        generator.initialize(KEY_SIZE, SecureRandom())

        val keyPair = generator.genKeyPair()
        val keyString = Base64.encodeToString(keyPair.public.encoded, Base64.NO_WRAP)

        return authRepository.getAuthId(keyString).mapSuccess {
            AuthModel(it, keyPair)
        
class CryptographyAppService @Inject constructor() : CryptographyService {
    override fun decrypt(stringAsByteArray: ByteArray, key: PrivateKey): String {
        val cipher: Cipher = Cipher.getInstance("RSA")
        cipher.init(Cipher.DECRYPT_MODE, key)
        return String(cipher.doFinal(stringAsByteArray))
    }
}
Public Key
MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEAoe3l5bTJD2hDKkfAc6vCytLtSt+MkxeteOXPQR4GF+25lBibHbszDVLTJxKcIuf1LFCNx234FgW018z7rTvgkplyz93vdhs0vRX4kv++K13lhvwWm1BQagTwwD1WLHR2dvCfZDcbtspZ89L7SfcTHjqwbkrNuzE0O/5xrOY5JrO+wwJixUljV4fA4DStWSBhBq3mXMrFTHS2eEiEWt03MnMXC2d74FMPUWzgpuKMhEwHpQm0GCN2ZIeper6KmU1Jf4CNLQfNdnP7KnNLYPnw8AKWZNI5h3WlDTpRd0QxukBV2d40PtIdBgnatjzZgdhEsJKQLeIkXDGBAo3VhizJifqVZo+QIvoe88YkhiQ2Tu95xBa0PaJofG2JlNcWs8aS6WYc0UqfUvjHl1I0n/fuWTguW7Hx3efzST4CwWy7A4gXFnyCegZ3edNI5aJsIa/+nUJsp5nURHdnBq0yoiWbhbh+eBmmPFT6+nej/Ouuu+8hYFkJAK7v1qw329Jr3HiJGuqRQpaRScap/mceqvQ/w2bDuDq15FTIf0VFqsL2G4KXUqfaVCk/o8i6Yen4uS7x8TY/yclJE7ujPjVEt2nWU2u4T7Qt5GAox1F0qmihgeUHYNBJcnQmJ6Tc9jQSaXYlObTYYboeadpzNRvIQJlg2W+kIcOYYypli3hEO5EWLJjJ6tpXVt0bX4qG7Zd0c74PLijGnooeWDkEZV8O3sl/71w1dMk2BcblWVA5M+1Pn372YSYeJ02pTuSMTbZpFXQKyDus1TWQVoTvYOzm/UTE2OleNT5Xuo/5R2J+8B/P3VZeVi4El3s5ik7E3Flb+jkeUwSKEyZyT1mqChct5HLieR7NC7iJDyPk4B5J+qzcEHc2hLGQQOz4odfxSi0P68a8MU3jB2OB5yCQGD/AdauPZUasEzJxy54UhjKxaqOxdFD8Cs+wqpWwLLbLDMebDjUba2SteZSxjUlftz+uA+Dv11ByQuzyI4F3TvTlqHohaWud8M11FmdK+ZDIR8lAZAm9ct14iivkNp1Gwq1BCF9yTf/tuy1R+5m1Flts1xp5mA64kN1lVRoz+MTb5ZI7JBCQSUFkqAoSrk1Af+wxJ0X0n6XSexFASMN7Llr74bIk0CDSgzVpGh8vJSCV4C8cuITO4GeGpDsiKRLlrBNTh49jsDzU9PccnAGCuBNqN4f4i8q7YoFuDMfjAkjFXr7bQBE20CKdh6et108m+TcMdQcD+Ugy5ahsFNHkoeT/xDGZF2lHsOh5arGqoclJoFeUrlIRH7Coish/0jM/Kl6r9gNWMyAPI7A/rQ9J5eTHIGNK2u/Q4sGmo3l7i6BUU/YtBGrXR0FlX0sThbPnWVHVQjj2BwIDAQAB
Private Key
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

来自API的return:

{
    "accessToken":"ArqtMnjpaLrsO5131a6xKi7CzccQzZG7//Za491lNZO7627Y76ekRpRJMyLCu5IQ4NMTT0z05bB60rf9e0Z++F7DFu0BCLgP56JSIbT75m7zFIP1YbweWgzR+RocU3m3IeR8KacGxI6gM/8m/rcWThcEtxPQ+fDBduSHEI/bCoOxMq2nHEVE0/xaaN9A41FjgASsz4ZsKJMu0qWr7gD+4o0GehH68Lekdme2uSbQZXiuCUp39SMA1WKP3VOYlRdgY+C5fmfLPP+lfEXc3lZnlDfbFUxPZQEXJT1zJA4lLAG/a1QWeCXizIj7tpQQ1iFqRIVwYMfqKQaJ2JdNFg479+VK2pYjHYiOVOT54SjItqweauauvU7RFK+0YTRICOa2ntokHbXwPjh6os/iBt/9bWSWjuJye7nJVsuleyPteGnJb88xijvijn1R8TWYZdmqwHBxVj4FHw2TAQ5AyG77O6vXLuQr8xNyXuBRsTKMINZUATQvSGfjwSCjwL+UveOev7GXhMjFRNJCD884b51bIiSWLa08whNxjiXSGzOC7CeCknd3TUwi9VK98PmVi6pbUpb3lpAieRrakA05m+Uskf/OHX0tSgR4FLz2vE9EPoPBjPdlrUtijLZ7DgNxHfnRlyWGFzxPSy/6oQKc6jFcEGpuDoC9rI2szMMnr28bumj9ov0SW2dIBx15ZmmQ3fgxQ81GcT9oUdm7U8mA8gZZm9fFXlhUZ4DJcPZ1M+ykjkHY+pvnvyGXR0E5S8U6NJRCnlwyQOPZdfn6KCFQ9rLUNusMnVupMpYiRRJKKlaGHiMnIfoh9y88n/8WC0IxDLKLe/Pv80417/NccgcLXNBhJZgreqeYc3cbrSk+H1hDQAcKwPJABDWt0vUop9/1MYV8h2dRmGiKBdByPRNEruWZwbmWZwBRR75GQVOCBq3F0Yo/9qVHePtqErv4xGtFdaiYS2ORhe+35fHUoOO+6frevhdbA5HpC+5kkVdB1Dt9E1v1h9KU7M+UmXipsW0TQ0WyGEcuFBmBaBdSAdCsM5WVdy5ifLLZ1bAndeqFq6/3t4Z3CPF9j7EQBlcUbXMB7BBWuDXmuJsE3hpqONFAdpTM47pvpjpJ1jKp3n1wKwmQTTH31e/j+gIirtMVcJ7G7Kxnp4MKB7tzZoW3Cou1UzSaib/WchGTUydA3OjLtDSvUXxxgg2DN4Wx4PwoFCy0jsRFeCVCLAzBCvkhuN1tfoLAUeh1UNbKZqJqvSPiDwbBsmpCXdgBCa3P9jPmJhGDSuqLe74W3dkRv0AqwE4OSOFgQsChuX+ti8EN4okqXhLpXVog3DoH8F8vm6hORJUN9SzXCRMvOqgdH4M2AxiE0KsTVQ=="
}

这是我的单元测试

@ExperimentalCoroutinesApi
class AuthenticationQrCodeViewModelTest {

@Test
    fun onGenerateRealToken_decryptRealToke () {
        val keypair = KeyPair(
            getPublicKey(
                "MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEAoe3l5bTJD2hDKkfAc6vCytLtSt+MkxeteOXPQR4GF+25lBibHbszDVLTJxKcIuf1LFCNx234FgW018z7rTvgkplyz93vdhs0vRX4kv++K13lhvwWm1BQagTwwD1WLHR2dvCfZDcbtspZ89L7SfcTHjqwbkrNuzE0O/5xrOY5JrO+wwJixUljV4fA4DStWSBhBq3mXMrFTHS2eEiEWt03MnMXC2d74FMPUWzgpuKMhEwHpQm0GCN2ZIeper6KmU1Jf4CNLQfNdnP7KnNLYPnw8AKWZNI5h3WlDTpRd0QxukBV2d40PtIdBgnatjzZgdhEsJKQLeIkXDGBAo3VhizJifqVZo+QIvoe88YkhiQ2Tu95xBa0PaJofG2JlNcWs8aS6WYc0UqfUvjHl1I0n/fuWTguW7Hx3efzST4CwWy7A4gXFnyCegZ3edNI5aJsIa/+nUJsp5nURHdnBq0yoiWbhbh+eBmmPFT6+nej/Ouuu+8hYFkJAK7v1qw329Jr3HiJGuqRQpaRScap/mceqvQ/w2bDuDq15FTIf0VFqsL2G4KXUqfaVCk/o8i6Yen4uS7x8TY/yclJE7ujPjVEt2nWU2u4T7Qt5GAox1F0qmihgeUHYNBJcnQmJ6Tc9jQSaXYlObTYYboeadpzNRvIQJlg2W+kIcOYYypli3hEO5EWLJjJ6tpXVt0bX4qG7Zd0c74PLijGnooeWDkEZV8O3sl/71w1dMk2BcblWVA5M+1Pn372YSYeJ02pTuSMTbZpFXQKyDus1TWQVoTvYOzm/UTE2OleNT5Xuo/5R2J+8B/P3VZeVi4El3s5ik7E3Flb+jkeUwSKEyZyT1mqChct5HLieR7NC7iJDyPk4B5J+qzcEHc2hLGQQOz4odfxSi0P68a8MU3jB2OB5yCQGD/AdauPZUasEzJxy54UhjKxaqOxdFD8Cs+wqpWwLLbLDMebDjUba2SteZSxjUlftz+uA+Dv11ByQuzyI4F3TvTlqHohaWud8M11FmdK+ZDIR8lAZAm9ct14iivkNp1Gwq1BCF9yTf/tuy1R+5m1Flts1xp5mA64kN1lVRoz+MTb5ZI7JBCQSUFkqAoSrk1Af+wxJ0X0n6XSexFASMN7Llr74bIk0CDSgzVpGh8vJSCV4C8cuITO4GeGpDsiKRLlrBNTh49jsDzU9PccnAGCuBNqN4f4i8q7YoFuDMfjAkjFXr7bQBE20CKdh6et108m+TcMdQcD+Ugy5ahsFNHkoeT/xDGZF2lHsOh5arGqoclJoFeUrlIRH7Coish/0jM/Kl6r9gNWMyAPI7A/rQ9J5eTHIGNK2u/Q4sGmo3l7i6BUU/YtBGrXR0FlX0sThbPnWVHVQjj2BwIDAQAB"
            ),
            getPrivateKey(
                "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"
            )
        )
        val authId = RandomUtil.string()
        val tokenModel = TokenModel(
            accessToken = "ArqtMnjpaLrsO5131a6xKi7CzccQzZG7//Za491lNZO7627Y76ekRpRJMyLCu5IQ4NMTT0z05bB60rf9e0Z++F7DFu0BCLgP56JSIbT75m7zFIP1YbweWgzR+RocU3m3IeR8KacGxI6gM/8m/rcWThcEtxPQ+fDBduSHEI/bCoOxMq2nHEVE0/xaaN9A41FjgASsz4ZsKJMu0qWr7gD+4o0GehH68Lekdme2uSbQZXiuCUp39SMA1WKP3VOYlRdgY+C5fmfLPP+lfEXc3lZnlDfbFUxPZQEXJT1zJA4lLAG/a1QWeCXizIj7tpQQ1iFqRIVwYMfqKQaJ2JdNFg479+VK2pYjHYiOVOT54SjItqweauauvU7RFK+0YTRICOa2ntokHbXwPjh6os/iBt/9bWSWjuJye7nJVsuleyPteGnJb88xijvijn1R8TWYZdmqwHBxVj4FHw2TAQ5AyG77O6vXLuQr8xNyXuBRsTKMINZUATQvSGfjwSCjwL+UveOev7GXhMjFRNJCD884b51bIiSWLa08whNxjiXSGzOC7CeCknd3TUwi9VK98PmVi6pbUpb3lpAieRrakA05m+Uskf/OHX0tSgR4FLz2vE9EPoPBjPdlrUtijLZ7DgNxHfnRlyWGFzxPSy/6oQKc6jFcEGpuDoC9rI2szMMnr28bumj9ov0SW2dIBx15ZmmQ3fgxQ81GcT9oUdm7U8mA8gZZm9fFXlhUZ4DJcPZ1M+ykjkHY+pvnvyGXR0E5S8U6NJRCnlwyQOPZdfn6KCFQ9rLUNusMnVupMpYiRRJKKlaGHiMnIfoh9y88n/8WC0IxDLKLe/Pv80417/NccgcLXNBhJZgreqeYc3cbrSk+H1hDQAcKwPJABDWt0vUop9/1MYV8h2dRmGiKBdByPRNEruWZwbmWZwBRR75GQVOCBq3F0Yo/9qVHePtqErv4xGtFdaiYS2ORhe+35fHUoOO+6frevhdbA5HpC+5kkVdB1Dt9E1v1h9KU7M+UmXipsW0TQ0WyGEcuFBmBaBdSAdCsM5WVdy5ifLLZ1bAndeqFq6/3t4Z3CPF9j7EQBlcUbXMB7BBWuDXmuJsE3hpqONFAdpTM47pvpjpJ1jKp3n1wKwmQTTH31e/j+gIirtMVcJ7G7Kxnp4MKB7tzZoW3Cou1UzSaib/WchGTUydA3OjLtDSvUXxxgg2DN4Wx4PwoFCy0jsRFeCVCLAzBCvkhuN1tfoLAUeh1UNbKZqJqvSPiDwbBsmpCXdgBCa3P9jPmJhGDSuqLe74W3dkRv0AqwE4OSOFgQsChuX+ti8EN4okqXhLpXVog3DoH8F8vm6hORJUN9SzXCRMvOqgdH4M2AxiE0KsTVQ==",
            refreshToken = "(I removed intentionally)"
        )

        prepareScenario(keypair, authId, Result.Success(tokenModel))

        coVerify(atLeast = 1) { initializeAuth() }
        coroutinesTestRule.testDispatcher.advanceTimeBy(QR_CODE_GENERATION_DELAY)

        val jwtToken = JwtToken(
            accessToken = "eyJraWQiOiJiNjRjNjZmZS00ZWY5LTExZTktODY0Ny1kNjYzYmQ4NzNkOTMiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJzdWIiOiI4MjE1NDliNi1iNzk1LTQwOGMtYjg4MS03MTA2OWY4NmE3OGMiLCJpc3MiOiJpRm9vZCIsInRlbmFudElkIjoiSUZPIiwidHlwZSI6ImFjY2Vzc190b2tlbiIsImV4cCI6MTU5OTg2MjU4OSwiaWF0IjoxNTk5ODU1Mzg5fQ.Qhf2pJctrhFBGGxAcat4xc0oVhytE-cffkoLt8kQZ7KcsWQzygYX2t00DGSSEepBUNUN3yl9Jr0MhRI6K-7sfgD-W8v4M8rE-kcbp4O0nZjLlWzNuZ8s6g5OPw9oIpaqORnNaPT9UpYDOqw-Zvr4E0syN46AwpE6QpZR2lWxr2JW665NoWXoPXoSiMWhwSTMi-IT-ZMDg-tVknC8Oikhu9tnIpJWTI7VKX5iG-93glJTZRkFGTAxV2hPTv9RAeRnGUhBCa2CCJXn8Y6phGd2qpECbQvc7LK04pHDqElvp5ofaqMM87bZKCuFDaqm2jIXylIxWgtkK7GtVrp9oZOf3A",
            refreshToken = "(I removed intentionally)",
            accountId = "",
            externalId = null
        )

        assertTrue(viewModel.viewState.action.value is AuthenticationQrCodeViewState.Action.GoToHome)
        coVerify(atLeast = 1) { setupCarAccount(eq(jwtToken), LoginTypeModel.LOGIN) }
    }

    private fun prepareScenario(
        keyPair: KeyPair = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA).genKeyPair(),
        authId: String = RandomUtil.string(),
        result: Result<TokenModel, ResultError> = Result.Error(ResultError.NetworkError())
    ) {
        coEvery { initializeAuth.invoke() } returns Result.Success(AuthModel(authId, keyPair))
        coEvery { fetchAuthToken.invoke(any()) } returns flowOf(result)
        coEvery {
            setupCarAccount.invoke(
                any(),
                any()
            )
        } returns Result.Success(Account(loginType = LoginTypeModel.LOGIN))

        mockkStatic("android.util.Base64")

        val arraySlot = slot<ByteArray>()
        val stringSlot = slot<String>()
        every { Base64.encodeToString(capture(arraySlot), any()) } answers {
            java.util.Base64.getEncoder()
                .encodeToString(arraySlot.captured)
        }
        every { Base64.decode(capture(stringSlot), any()) } answers {
            java.util.Base64.getDecoder()
                .decode(stringSlot.captured)
        }

        viewModel = AuthenticationQrCodeViewModel(
            viewState,
            initializeAuth,
            fetchAuthToken,
            setupCarAccount,
            cryptographyService
        )
    }

    private fun getPublicKey(publicKey: String): PublicKey? {
        return try {
            val keyFactory = KeyFactory.getInstance("RSA")
            val decodedKey = java.util.Base64.getDecoder().decode(publicKey)
            val keySpecX509 = X509EncodedKeySpec(decodedKey)
            keyFactory.generatePublic(keySpecX509)
        } catch (e: Exception) {
            throw java.lang.RuntimeException("Invalid public key.")
        }
    }

    private fun getPrivateKey(privateKey: String): PrivateKey? {
        return try {
            val keyFactory = KeyFactory.getInstance("RSA")
            val decodedKey = java.util.Base64.getDecoder().decode(privateKey)
            val keySpecX509 = PKCS8EncodedKeySpec(decodedKey)
            keyFactory.generatePrivate(keySpecX509)
        } catch (e: Exception) {
            throw java.lang.RuntimeException("Invalid private key.")
        }
    }

    private fun backendEncrypt(plain: String, key: PublicKey): String? {
        return try {
            val cipher = Cipher.getInstance("RSA")
            cipher.init(Cipher.ENCRYPT_MODE, key)
            val encryptedText = cipher.doFinal(plain.toByteArray())
            java.util.Base64.getEncoder().encodeToString(encryptedText)
        } catch (e: Exception) {
            throw RuntimeException("Failed to encrypt text.")
        }
    }

从这个docs:

Using the “RSA” transformation, the Cipher will default to ECB and PKCS1Padding.

因此,在您的 CryptographyAppService 中,您需要像这样设置 Cipher 实例:

val cipher: Cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")