different code's behavior in unit test and in runtime





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















The same code works in runtime and doesnt work in test



There is such code



private fun generatePrivateKeyFromText(key: String): Key {
val kf = KeyFactory.getInstance("RSA")
val keySpecPKCS8 = PKCS8EncodedKeySpec(Base64.decodeBase64(key))
return kf.generatePrivate(keySpecPKCS8)
}


When I run or debug app it works ok, but this code fails on generatePrivate while testing



java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence




@Test
fun decrypt() {
val encrypt = "MoRxCpLJNqxfXGVeU73zZFi+X2j2TLUTyIn1XRqCoEfeN8rNBR/YrEtumAz+8/0AaEsvx0+qTilfbw+edZd8Wfum4McWQ8oWXifvWLgoXybhxWUmCdi2fwA9Gw0parY6CSNYUDA2UuLrLLaDGMz/Jj4s4XmXKp5zuec1zXVdrPM="
val prkey = "MIICXAIBAAKBgQCAaTCQOxAZPfTXfgel2MMPUCLAf32TxfsXu71/c3mVFGtDPB+7IpmxCmEvAv6nlq1ymX1zRR5gIzNt4DZoM0RhE58eoksUXcmFcRnMX5V4bnI8DitHLdB2EZzdvnPX0Umzs+tE7I1ouDIocNQRsEoQeDcNPfz5av2zMPsg0Xl/yQIDAQABAoGAV8UOX5cvQsGZZ+2J1q8ZbI8OodrCf83z+V3mgYXxVZe2VSd0XNmiiWMZ2CNI4k3YUhtdpvtYbsfAsFpvdbuNAXMW82Zwsd0oluPzzoLELGkFvaUJlh2YGmizrBnEwvF0usJYwjsjUbXw3o1xKX8ILk5FBfdr2+L65YIIZ0UhqoECQQD/B0P8iZhoOTx7myhwlFCuVeSadwaOMGy2CgXRLvTFAtstz8YVO+D+yPKsEpAvMlFgEnkTt7tl8DRxMpKnfmO5AkEAgOZudjUD72xWfSJpCEcX76WGSASWE+fLCZ8C/HumIZ+0trW5/bsmBrI/6SldEJcy4b2bHh2nOggC/6R5rEUkkQJAAg779IDj0wuLOnAxLl90G0QkOT72tZUce4evLlYTsbdpL4B619cI5OWYV906frcIQx9DDO6xu4vp0HQZDPMPOQJAOVbH8ntY2ctmmdmRwWXmpusJ1cV8gTROJGSArpHOcAycFd628sCqhLYMKgsFZBjuQG7YrsfgGLdxpgijO1eykQJBAOE8+BrQwFWyOcgnUShPHo8mDOBkeplGr9VZdnWktac2aBr1Biovy+pipUyjSCAaFgOsSU0FDcK0I5ulTOpgMRg="
val decrypt = CryptoService.decrypt(encrypt, prkey)
assertEquals("Pika-pika", decrypt)
}




fun decrypt(ciphertext: String, key: String): String {
var decodedBytes: ByteArray? = null
try {
val c = Cipher.getInstance("RSA")
c.init(Cipher.DECRYPT_MODE, generatePrivateKeyFromText(key))
decodedBytes = c.doFinal(Base64.decodeBase64(ciphertext))

} catch (e: Exception) {
Log.e("Crypto", "RSA decryption error: $e")
}
return String(decodedBytes ?: ByteArray(0))
}




Working function is in Fragment



 private fun testCrypto() {
val encrypt = "MoRxCpLJNqxfXGVeU73zZFi+X2j2TLUTyIn1XRqCoEfeN8rNBR/YrEtumAz+8/0AaEsvx0+qTilfbw+edZd8Wfum4McWQ8oWXifvWLgoXybhxWUmCdi2fwA9Gw0parY6CSNYUDA2UuLrLLaDGMz/Jj4s4XmXKp5zuec1zXVdrPM="
val prkey = "MIICXAIBAAKBgQCAaTCQOxAZPfTXfgel2MMPUCLAf32TxfsXu71/c3mVFGtDPB+7IpmxCmEvAv6nlq1ymX1zRR5gIzNt4DZoM0RhE58eoksUXcmFcRnMX5V4bnI8DitHLdB2EZzdvnPX0Umzs+tE7I1ouDIocNQRsEoQeDcNPfz5av2zMPsg0Xl/yQIDAQABAoGAV8UOX5cvQsGZZ+2J1q8ZbI8OodrCf83z+V3mgYXxVZe2VSd0XNmiiWMZ2CNI4k3YUhtdpvtYbsfAsFpvdbuNAXMW82Zwsd0oluPzzoLELGkFvaUJlh2YGmizrBnEwvF0usJYwjsjUbXw3o1xKX8ILk5FBfdr2+L65YIIZ0UhqoECQQD/B0P8iZhoOTx7myhwlFCuVeSadwaOMGy2CgXRLvTFAtstz8YVO+D+yPKsEpAvMlFgEnkTt7tl8DRxMpKnfmO5AkEAgOZudjUD72xWfSJpCEcX76WGSASWE+fLCZ8C/HumIZ+0trW5/bsmBrI/6SldEJcy4b2bHh2nOggC/6R5rEUkkQJAAg779IDj0wuLOnAxLl90G0QkOT72tZUce4evLlYTsbdpL4B619cI5OWYV906frcIQx9DDO6xu4vp0HQZDPMPOQJAOVbH8ntY2ctmmdmRwWXmpusJ1cV8gTROJGSArpHOcAycFd628sCqhLYMKgsFZBjuQG7YrsfgGLdxpgijO1eykQJBAOE8+BrQwFWyOcgnUShPHo8mDOBkeplGr9VZdnWktac2aBr1Biovy+pipUyjSCAaFgOsSU0FDcK0I5ulTOpgMRg="
val decrypt = CryptoService.decrypt(encrypt, prkey)
println(decrypt) // "Pika-pika"
}


I call it on onViewCreated





Updated:



I added BC provider (thanks, @JamesKPolk)



private fun generatePrivateKeyFromText(key: String): Key {
Security.addProvider(BouncyCastleProvider())
val kf = KeyFactory.getInstance(algorithm)
val keySpecPKCS8 = PKCS8EncodedKeySpec(Base64.decodeBase64(key))
return kf.generatePrivate(keySpecPKCS8)
}


But it is still ok in runtime and not while testing



javax.crypto.BadPaddingException: Decryption error


So problem for different running code didnt go.



What the difference between runtime and test which crashes code?










share|improve this question

























  • ah, but that's a different error than the 1st one.

    – James K Polk
    Nov 22 '18 at 17:15











  • And again only in unit test. I rewrote text and header so.

    – Kirill Matrosov
    Nov 22 '18 at 17:16











  • I use org.apache.commons.codec.binary.Base64 . The case about it is described here

    – Kirill Matrosov
    Nov 22 '18 at 17:22











  • ahhh, so the unit tests don't really run on Android.

    – James K Polk
    Nov 22 '18 at 17:27






  • 1





    See my latest edits to my answer.

    – James K Polk
    Nov 22 '18 at 17:53


















0















The same code works in runtime and doesnt work in test



There is such code



private fun generatePrivateKeyFromText(key: String): Key {
val kf = KeyFactory.getInstance("RSA")
val keySpecPKCS8 = PKCS8EncodedKeySpec(Base64.decodeBase64(key))
return kf.generatePrivate(keySpecPKCS8)
}


When I run or debug app it works ok, but this code fails on generatePrivate while testing



java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence




@Test
fun decrypt() {
val encrypt = "MoRxCpLJNqxfXGVeU73zZFi+X2j2TLUTyIn1XRqCoEfeN8rNBR/YrEtumAz+8/0AaEsvx0+qTilfbw+edZd8Wfum4McWQ8oWXifvWLgoXybhxWUmCdi2fwA9Gw0parY6CSNYUDA2UuLrLLaDGMz/Jj4s4XmXKp5zuec1zXVdrPM="
val prkey = "MIICXAIBAAKBgQCAaTCQOxAZPfTXfgel2MMPUCLAf32TxfsXu71/c3mVFGtDPB+7IpmxCmEvAv6nlq1ymX1zRR5gIzNt4DZoM0RhE58eoksUXcmFcRnMX5V4bnI8DitHLdB2EZzdvnPX0Umzs+tE7I1ouDIocNQRsEoQeDcNPfz5av2zMPsg0Xl/yQIDAQABAoGAV8UOX5cvQsGZZ+2J1q8ZbI8OodrCf83z+V3mgYXxVZe2VSd0XNmiiWMZ2CNI4k3YUhtdpvtYbsfAsFpvdbuNAXMW82Zwsd0oluPzzoLELGkFvaUJlh2YGmizrBnEwvF0usJYwjsjUbXw3o1xKX8ILk5FBfdr2+L65YIIZ0UhqoECQQD/B0P8iZhoOTx7myhwlFCuVeSadwaOMGy2CgXRLvTFAtstz8YVO+D+yPKsEpAvMlFgEnkTt7tl8DRxMpKnfmO5AkEAgOZudjUD72xWfSJpCEcX76WGSASWE+fLCZ8C/HumIZ+0trW5/bsmBrI/6SldEJcy4b2bHh2nOggC/6R5rEUkkQJAAg779IDj0wuLOnAxLl90G0QkOT72tZUce4evLlYTsbdpL4B619cI5OWYV906frcIQx9DDO6xu4vp0HQZDPMPOQJAOVbH8ntY2ctmmdmRwWXmpusJ1cV8gTROJGSArpHOcAycFd628sCqhLYMKgsFZBjuQG7YrsfgGLdxpgijO1eykQJBAOE8+BrQwFWyOcgnUShPHo8mDOBkeplGr9VZdnWktac2aBr1Biovy+pipUyjSCAaFgOsSU0FDcK0I5ulTOpgMRg="
val decrypt = CryptoService.decrypt(encrypt, prkey)
assertEquals("Pika-pika", decrypt)
}




fun decrypt(ciphertext: String, key: String): String {
var decodedBytes: ByteArray? = null
try {
val c = Cipher.getInstance("RSA")
c.init(Cipher.DECRYPT_MODE, generatePrivateKeyFromText(key))
decodedBytes = c.doFinal(Base64.decodeBase64(ciphertext))

} catch (e: Exception) {
Log.e("Crypto", "RSA decryption error: $e")
}
return String(decodedBytes ?: ByteArray(0))
}




Working function is in Fragment



 private fun testCrypto() {
val encrypt = "MoRxCpLJNqxfXGVeU73zZFi+X2j2TLUTyIn1XRqCoEfeN8rNBR/YrEtumAz+8/0AaEsvx0+qTilfbw+edZd8Wfum4McWQ8oWXifvWLgoXybhxWUmCdi2fwA9Gw0parY6CSNYUDA2UuLrLLaDGMz/Jj4s4XmXKp5zuec1zXVdrPM="
val prkey = "MIICXAIBAAKBgQCAaTCQOxAZPfTXfgel2MMPUCLAf32TxfsXu71/c3mVFGtDPB+7IpmxCmEvAv6nlq1ymX1zRR5gIzNt4DZoM0RhE58eoksUXcmFcRnMX5V4bnI8DitHLdB2EZzdvnPX0Umzs+tE7I1ouDIocNQRsEoQeDcNPfz5av2zMPsg0Xl/yQIDAQABAoGAV8UOX5cvQsGZZ+2J1q8ZbI8OodrCf83z+V3mgYXxVZe2VSd0XNmiiWMZ2CNI4k3YUhtdpvtYbsfAsFpvdbuNAXMW82Zwsd0oluPzzoLELGkFvaUJlh2YGmizrBnEwvF0usJYwjsjUbXw3o1xKX8ILk5FBfdr2+L65YIIZ0UhqoECQQD/B0P8iZhoOTx7myhwlFCuVeSadwaOMGy2CgXRLvTFAtstz8YVO+D+yPKsEpAvMlFgEnkTt7tl8DRxMpKnfmO5AkEAgOZudjUD72xWfSJpCEcX76WGSASWE+fLCZ8C/HumIZ+0trW5/bsmBrI/6SldEJcy4b2bHh2nOggC/6R5rEUkkQJAAg779IDj0wuLOnAxLl90G0QkOT72tZUce4evLlYTsbdpL4B619cI5OWYV906frcIQx9DDO6xu4vp0HQZDPMPOQJAOVbH8ntY2ctmmdmRwWXmpusJ1cV8gTROJGSArpHOcAycFd628sCqhLYMKgsFZBjuQG7YrsfgGLdxpgijO1eykQJBAOE8+BrQwFWyOcgnUShPHo8mDOBkeplGr9VZdnWktac2aBr1Biovy+pipUyjSCAaFgOsSU0FDcK0I5ulTOpgMRg="
val decrypt = CryptoService.decrypt(encrypt, prkey)
println(decrypt) // "Pika-pika"
}


I call it on onViewCreated





Updated:



I added BC provider (thanks, @JamesKPolk)



private fun generatePrivateKeyFromText(key: String): Key {
Security.addProvider(BouncyCastleProvider())
val kf = KeyFactory.getInstance(algorithm)
val keySpecPKCS8 = PKCS8EncodedKeySpec(Base64.decodeBase64(key))
return kf.generatePrivate(keySpecPKCS8)
}


But it is still ok in runtime and not while testing



javax.crypto.BadPaddingException: Decryption error


So problem for different running code didnt go.



What the difference between runtime and test which crashes code?










share|improve this question

























  • ah, but that's a different error than the 1st one.

    – James K Polk
    Nov 22 '18 at 17:15











  • And again only in unit test. I rewrote text and header so.

    – Kirill Matrosov
    Nov 22 '18 at 17:16











  • I use org.apache.commons.codec.binary.Base64 . The case about it is described here

    – Kirill Matrosov
    Nov 22 '18 at 17:22











  • ahhh, so the unit tests don't really run on Android.

    – James K Polk
    Nov 22 '18 at 17:27






  • 1





    See my latest edits to my answer.

    – James K Polk
    Nov 22 '18 at 17:53














0












0








0








The same code works in runtime and doesnt work in test



There is such code



private fun generatePrivateKeyFromText(key: String): Key {
val kf = KeyFactory.getInstance("RSA")
val keySpecPKCS8 = PKCS8EncodedKeySpec(Base64.decodeBase64(key))
return kf.generatePrivate(keySpecPKCS8)
}


When I run or debug app it works ok, but this code fails on generatePrivate while testing



java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence




@Test
fun decrypt() {
val encrypt = "MoRxCpLJNqxfXGVeU73zZFi+X2j2TLUTyIn1XRqCoEfeN8rNBR/YrEtumAz+8/0AaEsvx0+qTilfbw+edZd8Wfum4McWQ8oWXifvWLgoXybhxWUmCdi2fwA9Gw0parY6CSNYUDA2UuLrLLaDGMz/Jj4s4XmXKp5zuec1zXVdrPM="
val prkey = "MIICXAIBAAKBgQCAaTCQOxAZPfTXfgel2MMPUCLAf32TxfsXu71/c3mVFGtDPB+7IpmxCmEvAv6nlq1ymX1zRR5gIzNt4DZoM0RhE58eoksUXcmFcRnMX5V4bnI8DitHLdB2EZzdvnPX0Umzs+tE7I1ouDIocNQRsEoQeDcNPfz5av2zMPsg0Xl/yQIDAQABAoGAV8UOX5cvQsGZZ+2J1q8ZbI8OodrCf83z+V3mgYXxVZe2VSd0XNmiiWMZ2CNI4k3YUhtdpvtYbsfAsFpvdbuNAXMW82Zwsd0oluPzzoLELGkFvaUJlh2YGmizrBnEwvF0usJYwjsjUbXw3o1xKX8ILk5FBfdr2+L65YIIZ0UhqoECQQD/B0P8iZhoOTx7myhwlFCuVeSadwaOMGy2CgXRLvTFAtstz8YVO+D+yPKsEpAvMlFgEnkTt7tl8DRxMpKnfmO5AkEAgOZudjUD72xWfSJpCEcX76WGSASWE+fLCZ8C/HumIZ+0trW5/bsmBrI/6SldEJcy4b2bHh2nOggC/6R5rEUkkQJAAg779IDj0wuLOnAxLl90G0QkOT72tZUce4evLlYTsbdpL4B619cI5OWYV906frcIQx9DDO6xu4vp0HQZDPMPOQJAOVbH8ntY2ctmmdmRwWXmpusJ1cV8gTROJGSArpHOcAycFd628sCqhLYMKgsFZBjuQG7YrsfgGLdxpgijO1eykQJBAOE8+BrQwFWyOcgnUShPHo8mDOBkeplGr9VZdnWktac2aBr1Biovy+pipUyjSCAaFgOsSU0FDcK0I5ulTOpgMRg="
val decrypt = CryptoService.decrypt(encrypt, prkey)
assertEquals("Pika-pika", decrypt)
}




fun decrypt(ciphertext: String, key: String): String {
var decodedBytes: ByteArray? = null
try {
val c = Cipher.getInstance("RSA")
c.init(Cipher.DECRYPT_MODE, generatePrivateKeyFromText(key))
decodedBytes = c.doFinal(Base64.decodeBase64(ciphertext))

} catch (e: Exception) {
Log.e("Crypto", "RSA decryption error: $e")
}
return String(decodedBytes ?: ByteArray(0))
}




Working function is in Fragment



 private fun testCrypto() {
val encrypt = "MoRxCpLJNqxfXGVeU73zZFi+X2j2TLUTyIn1XRqCoEfeN8rNBR/YrEtumAz+8/0AaEsvx0+qTilfbw+edZd8Wfum4McWQ8oWXifvWLgoXybhxWUmCdi2fwA9Gw0parY6CSNYUDA2UuLrLLaDGMz/Jj4s4XmXKp5zuec1zXVdrPM="
val prkey = "MIICXAIBAAKBgQCAaTCQOxAZPfTXfgel2MMPUCLAf32TxfsXu71/c3mVFGtDPB+7IpmxCmEvAv6nlq1ymX1zRR5gIzNt4DZoM0RhE58eoksUXcmFcRnMX5V4bnI8DitHLdB2EZzdvnPX0Umzs+tE7I1ouDIocNQRsEoQeDcNPfz5av2zMPsg0Xl/yQIDAQABAoGAV8UOX5cvQsGZZ+2J1q8ZbI8OodrCf83z+V3mgYXxVZe2VSd0XNmiiWMZ2CNI4k3YUhtdpvtYbsfAsFpvdbuNAXMW82Zwsd0oluPzzoLELGkFvaUJlh2YGmizrBnEwvF0usJYwjsjUbXw3o1xKX8ILk5FBfdr2+L65YIIZ0UhqoECQQD/B0P8iZhoOTx7myhwlFCuVeSadwaOMGy2CgXRLvTFAtstz8YVO+D+yPKsEpAvMlFgEnkTt7tl8DRxMpKnfmO5AkEAgOZudjUD72xWfSJpCEcX76WGSASWE+fLCZ8C/HumIZ+0trW5/bsmBrI/6SldEJcy4b2bHh2nOggC/6R5rEUkkQJAAg779IDj0wuLOnAxLl90G0QkOT72tZUce4evLlYTsbdpL4B619cI5OWYV906frcIQx9DDO6xu4vp0HQZDPMPOQJAOVbH8ntY2ctmmdmRwWXmpusJ1cV8gTROJGSArpHOcAycFd628sCqhLYMKgsFZBjuQG7YrsfgGLdxpgijO1eykQJBAOE8+BrQwFWyOcgnUShPHo8mDOBkeplGr9VZdnWktac2aBr1Biovy+pipUyjSCAaFgOsSU0FDcK0I5ulTOpgMRg="
val decrypt = CryptoService.decrypt(encrypt, prkey)
println(decrypt) // "Pika-pika"
}


I call it on onViewCreated





Updated:



I added BC provider (thanks, @JamesKPolk)



private fun generatePrivateKeyFromText(key: String): Key {
Security.addProvider(BouncyCastleProvider())
val kf = KeyFactory.getInstance(algorithm)
val keySpecPKCS8 = PKCS8EncodedKeySpec(Base64.decodeBase64(key))
return kf.generatePrivate(keySpecPKCS8)
}


But it is still ok in runtime and not while testing



javax.crypto.BadPaddingException: Decryption error


So problem for different running code didnt go.



What the difference between runtime and test which crashes code?










share|improve this question
















The same code works in runtime and doesnt work in test



There is such code



private fun generatePrivateKeyFromText(key: String): Key {
val kf = KeyFactory.getInstance("RSA")
val keySpecPKCS8 = PKCS8EncodedKeySpec(Base64.decodeBase64(key))
return kf.generatePrivate(keySpecPKCS8)
}


When I run or debug app it works ok, but this code fails on generatePrivate while testing



java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence




@Test
fun decrypt() {
val encrypt = "MoRxCpLJNqxfXGVeU73zZFi+X2j2TLUTyIn1XRqCoEfeN8rNBR/YrEtumAz+8/0AaEsvx0+qTilfbw+edZd8Wfum4McWQ8oWXifvWLgoXybhxWUmCdi2fwA9Gw0parY6CSNYUDA2UuLrLLaDGMz/Jj4s4XmXKp5zuec1zXVdrPM="
val prkey = "MIICXAIBAAKBgQCAaTCQOxAZPfTXfgel2MMPUCLAf32TxfsXu71/c3mVFGtDPB+7IpmxCmEvAv6nlq1ymX1zRR5gIzNt4DZoM0RhE58eoksUXcmFcRnMX5V4bnI8DitHLdB2EZzdvnPX0Umzs+tE7I1ouDIocNQRsEoQeDcNPfz5av2zMPsg0Xl/yQIDAQABAoGAV8UOX5cvQsGZZ+2J1q8ZbI8OodrCf83z+V3mgYXxVZe2VSd0XNmiiWMZ2CNI4k3YUhtdpvtYbsfAsFpvdbuNAXMW82Zwsd0oluPzzoLELGkFvaUJlh2YGmizrBnEwvF0usJYwjsjUbXw3o1xKX8ILk5FBfdr2+L65YIIZ0UhqoECQQD/B0P8iZhoOTx7myhwlFCuVeSadwaOMGy2CgXRLvTFAtstz8YVO+D+yPKsEpAvMlFgEnkTt7tl8DRxMpKnfmO5AkEAgOZudjUD72xWfSJpCEcX76WGSASWE+fLCZ8C/HumIZ+0trW5/bsmBrI/6SldEJcy4b2bHh2nOggC/6R5rEUkkQJAAg779IDj0wuLOnAxLl90G0QkOT72tZUce4evLlYTsbdpL4B619cI5OWYV906frcIQx9DDO6xu4vp0HQZDPMPOQJAOVbH8ntY2ctmmdmRwWXmpusJ1cV8gTROJGSArpHOcAycFd628sCqhLYMKgsFZBjuQG7YrsfgGLdxpgijO1eykQJBAOE8+BrQwFWyOcgnUShPHo8mDOBkeplGr9VZdnWktac2aBr1Biovy+pipUyjSCAaFgOsSU0FDcK0I5ulTOpgMRg="
val decrypt = CryptoService.decrypt(encrypt, prkey)
assertEquals("Pika-pika", decrypt)
}




fun decrypt(ciphertext: String, key: String): String {
var decodedBytes: ByteArray? = null
try {
val c = Cipher.getInstance("RSA")
c.init(Cipher.DECRYPT_MODE, generatePrivateKeyFromText(key))
decodedBytes = c.doFinal(Base64.decodeBase64(ciphertext))

} catch (e: Exception) {
Log.e("Crypto", "RSA decryption error: $e")
}
return String(decodedBytes ?: ByteArray(0))
}




Working function is in Fragment



 private fun testCrypto() {
val encrypt = "MoRxCpLJNqxfXGVeU73zZFi+X2j2TLUTyIn1XRqCoEfeN8rNBR/YrEtumAz+8/0AaEsvx0+qTilfbw+edZd8Wfum4McWQ8oWXifvWLgoXybhxWUmCdi2fwA9Gw0parY6CSNYUDA2UuLrLLaDGMz/Jj4s4XmXKp5zuec1zXVdrPM="
val prkey = "MIICXAIBAAKBgQCAaTCQOxAZPfTXfgel2MMPUCLAf32TxfsXu71/c3mVFGtDPB+7IpmxCmEvAv6nlq1ymX1zRR5gIzNt4DZoM0RhE58eoksUXcmFcRnMX5V4bnI8DitHLdB2EZzdvnPX0Umzs+tE7I1ouDIocNQRsEoQeDcNPfz5av2zMPsg0Xl/yQIDAQABAoGAV8UOX5cvQsGZZ+2J1q8ZbI8OodrCf83z+V3mgYXxVZe2VSd0XNmiiWMZ2CNI4k3YUhtdpvtYbsfAsFpvdbuNAXMW82Zwsd0oluPzzoLELGkFvaUJlh2YGmizrBnEwvF0usJYwjsjUbXw3o1xKX8ILk5FBfdr2+L65YIIZ0UhqoECQQD/B0P8iZhoOTx7myhwlFCuVeSadwaOMGy2CgXRLvTFAtstz8YVO+D+yPKsEpAvMlFgEnkTt7tl8DRxMpKnfmO5AkEAgOZudjUD72xWfSJpCEcX76WGSASWE+fLCZ8C/HumIZ+0trW5/bsmBrI/6SldEJcy4b2bHh2nOggC/6R5rEUkkQJAAg779IDj0wuLOnAxLl90G0QkOT72tZUce4evLlYTsbdpL4B619cI5OWYV906frcIQx9DDO6xu4vp0HQZDPMPOQJAOVbH8ntY2ctmmdmRwWXmpusJ1cV8gTROJGSArpHOcAycFd628sCqhLYMKgsFZBjuQG7YrsfgGLdxpgijO1eykQJBAOE8+BrQwFWyOcgnUShPHo8mDOBkeplGr9VZdnWktac2aBr1Biovy+pipUyjSCAaFgOsSU0FDcK0I5ulTOpgMRg="
val decrypt = CryptoService.decrypt(encrypt, prkey)
println(decrypt) // "Pika-pika"
}


I call it on onViewCreated





Updated:



I added BC provider (thanks, @JamesKPolk)



private fun generatePrivateKeyFromText(key: String): Key {
Security.addProvider(BouncyCastleProvider())
val kf = KeyFactory.getInstance(algorithm)
val keySpecPKCS8 = PKCS8EncodedKeySpec(Base64.decodeBase64(key))
return kf.generatePrivate(keySpecPKCS8)
}


But it is still ok in runtime and not while testing



javax.crypto.BadPaddingException: Decryption error


So problem for different running code didnt go.



What the difference between runtime and test which crashes code?







android kotlin






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 28 '18 at 17:54









Jayson Minard

42.4k19117177




42.4k19117177










asked Nov 22 '18 at 16:26









Kirill MatrosovKirill Matrosov

1,65911023




1,65911023













  • ah, but that's a different error than the 1st one.

    – James K Polk
    Nov 22 '18 at 17:15











  • And again only in unit test. I rewrote text and header so.

    – Kirill Matrosov
    Nov 22 '18 at 17:16











  • I use org.apache.commons.codec.binary.Base64 . The case about it is described here

    – Kirill Matrosov
    Nov 22 '18 at 17:22











  • ahhh, so the unit tests don't really run on Android.

    – James K Polk
    Nov 22 '18 at 17:27






  • 1





    See my latest edits to my answer.

    – James K Polk
    Nov 22 '18 at 17:53



















  • ah, but that's a different error than the 1st one.

    – James K Polk
    Nov 22 '18 at 17:15











  • And again only in unit test. I rewrote text and header so.

    – Kirill Matrosov
    Nov 22 '18 at 17:16











  • I use org.apache.commons.codec.binary.Base64 . The case about it is described here

    – Kirill Matrosov
    Nov 22 '18 at 17:22











  • ahhh, so the unit tests don't really run on Android.

    – James K Polk
    Nov 22 '18 at 17:27






  • 1





    See my latest edits to my answer.

    – James K Polk
    Nov 22 '18 at 17:53

















ah, but that's a different error than the 1st one.

– James K Polk
Nov 22 '18 at 17:15





ah, but that's a different error than the 1st one.

– James K Polk
Nov 22 '18 at 17:15













And again only in unit test. I rewrote text and header so.

– Kirill Matrosov
Nov 22 '18 at 17:16





And again only in unit test. I rewrote text and header so.

– Kirill Matrosov
Nov 22 '18 at 17:16













I use org.apache.commons.codec.binary.Base64 . The case about it is described here

– Kirill Matrosov
Nov 22 '18 at 17:22





I use org.apache.commons.codec.binary.Base64 . The case about it is described here

– Kirill Matrosov
Nov 22 '18 at 17:22













ahhh, so the unit tests don't really run on Android.

– James K Polk
Nov 22 '18 at 17:27





ahhh, so the unit tests don't really run on Android.

– James K Polk
Nov 22 '18 at 17:27




1




1





See my latest edits to my answer.

– James K Polk
Nov 22 '18 at 17:53





See my latest edits to my answer.

– James K Polk
Nov 22 '18 at 17:53












1 Answer
1






active

oldest

votes


















1














The issue is that the private key is not a PKCS8EncodedKeySpec, but rather an RSAPrivateKey object from PKCS#1. The BC provider, however, will still decode this mistake without complaint. However, other providers will rightfully complain. My guess is that the runtime is using an older version of Android where the default provider is BC, but your test is using a newer version where that isn't the case.



The fix is to make your private key a proper PKCS8EncodedKeySpec. Alternatively, you can explicitly request the "BC" provider. To do so, you need to specify "BC" in the getInstance() call: val keyFactory = KeyFactory.getInstance("RSA", "BC")



However, note that it appears that BC provider support is on its way out.



To convert a private key in the PKCS#1 format, either wrap a 'BEGIN RSA PRIVATE KEY'-style header and footer around the base64 blob or decode the base64 blob and place that in a file, then run:



openssl pkcs8 -topk8 -in privkey.pem  -outform der -nocrypt | openssl base64 -A


or



openssl pkcs8 -topk8 -in privkey.der -inform der -nocrypt  | openssl base64 -A


A second issue comes from relying on defaults. Instead of doing



val c = Cipher.getInstance("RSA")


which gets you defaults for mode and padding and thus is non-portable, always specify the full "algorithm/mode/padding" transformation string to Cipher.getInstance(). In you case, it appears the data is not padded (an insecure mode) you'd need something like



val c = Cipher.getInstance("RSA/ECB/NoPadding")


However, you really should use proper randomized padding, and currently that is OAEP padding.



Summary



The runtime environment is Android, but I think the test environment is Oracle Java (or maybe openjdk). There are evidently two critical differences in those environments:




  1. Android uses the BC provider for KeyFactory which will handle private keys encoded in PKCS#1 RSAPrivateKey format. Oracle Java only supports PKCS8 encoded keys.

  2. In Android, Cipher.getInstance("RSA") defaults to Cipher.getInstance("RSA/ECB/NoPadding"), but Oracle Java defaults to Cipher.getInstance("RSA/ECB/PKCS1Padding")






share|improve this answer


























  • I have just checked on 4th Android and the last. Runtime is still working. So I dont think that the reason in versions

    – Kirill Matrosov
    Nov 22 '18 at 16:49











  • I will try to experiment with your code but I'm not a Kotlin programmer.

    – James K Polk
    Nov 22 '18 at 17:07











  • It helped. But I still dont understand why the same code works in runtime and doesnt work while testing

    – Kirill Matrosov
    Nov 23 '18 at 8:52






  • 1





    I'll add that info to the answer. Let me know if it still remains unclear.

    – James K Polk
    Nov 23 '18 at 14:16












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435000%2fdifferent-codes-behavior-in-unit-test-and-in-runtime%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














The issue is that the private key is not a PKCS8EncodedKeySpec, but rather an RSAPrivateKey object from PKCS#1. The BC provider, however, will still decode this mistake without complaint. However, other providers will rightfully complain. My guess is that the runtime is using an older version of Android where the default provider is BC, but your test is using a newer version where that isn't the case.



The fix is to make your private key a proper PKCS8EncodedKeySpec. Alternatively, you can explicitly request the "BC" provider. To do so, you need to specify "BC" in the getInstance() call: val keyFactory = KeyFactory.getInstance("RSA", "BC")



However, note that it appears that BC provider support is on its way out.



To convert a private key in the PKCS#1 format, either wrap a 'BEGIN RSA PRIVATE KEY'-style header and footer around the base64 blob or decode the base64 blob and place that in a file, then run:



openssl pkcs8 -topk8 -in privkey.pem  -outform der -nocrypt | openssl base64 -A


or



openssl pkcs8 -topk8 -in privkey.der -inform der -nocrypt  | openssl base64 -A


A second issue comes from relying on defaults. Instead of doing



val c = Cipher.getInstance("RSA")


which gets you defaults for mode and padding and thus is non-portable, always specify the full "algorithm/mode/padding" transformation string to Cipher.getInstance(). In you case, it appears the data is not padded (an insecure mode) you'd need something like



val c = Cipher.getInstance("RSA/ECB/NoPadding")


However, you really should use proper randomized padding, and currently that is OAEP padding.



Summary



The runtime environment is Android, but I think the test environment is Oracle Java (or maybe openjdk). There are evidently two critical differences in those environments:




  1. Android uses the BC provider for KeyFactory which will handle private keys encoded in PKCS#1 RSAPrivateKey format. Oracle Java only supports PKCS8 encoded keys.

  2. In Android, Cipher.getInstance("RSA") defaults to Cipher.getInstance("RSA/ECB/NoPadding"), but Oracle Java defaults to Cipher.getInstance("RSA/ECB/PKCS1Padding")






share|improve this answer


























  • I have just checked on 4th Android and the last. Runtime is still working. So I dont think that the reason in versions

    – Kirill Matrosov
    Nov 22 '18 at 16:49











  • I will try to experiment with your code but I'm not a Kotlin programmer.

    – James K Polk
    Nov 22 '18 at 17:07











  • It helped. But I still dont understand why the same code works in runtime and doesnt work while testing

    – Kirill Matrosov
    Nov 23 '18 at 8:52






  • 1





    I'll add that info to the answer. Let me know if it still remains unclear.

    – James K Polk
    Nov 23 '18 at 14:16
















1














The issue is that the private key is not a PKCS8EncodedKeySpec, but rather an RSAPrivateKey object from PKCS#1. The BC provider, however, will still decode this mistake without complaint. However, other providers will rightfully complain. My guess is that the runtime is using an older version of Android where the default provider is BC, but your test is using a newer version where that isn't the case.



The fix is to make your private key a proper PKCS8EncodedKeySpec. Alternatively, you can explicitly request the "BC" provider. To do so, you need to specify "BC" in the getInstance() call: val keyFactory = KeyFactory.getInstance("RSA", "BC")



However, note that it appears that BC provider support is on its way out.



To convert a private key in the PKCS#1 format, either wrap a 'BEGIN RSA PRIVATE KEY'-style header and footer around the base64 blob or decode the base64 blob and place that in a file, then run:



openssl pkcs8 -topk8 -in privkey.pem  -outform der -nocrypt | openssl base64 -A


or



openssl pkcs8 -topk8 -in privkey.der -inform der -nocrypt  | openssl base64 -A


A second issue comes from relying on defaults. Instead of doing



val c = Cipher.getInstance("RSA")


which gets you defaults for mode and padding and thus is non-portable, always specify the full "algorithm/mode/padding" transformation string to Cipher.getInstance(). In you case, it appears the data is not padded (an insecure mode) you'd need something like



val c = Cipher.getInstance("RSA/ECB/NoPadding")


However, you really should use proper randomized padding, and currently that is OAEP padding.



Summary



The runtime environment is Android, but I think the test environment is Oracle Java (or maybe openjdk). There are evidently two critical differences in those environments:




  1. Android uses the BC provider for KeyFactory which will handle private keys encoded in PKCS#1 RSAPrivateKey format. Oracle Java only supports PKCS8 encoded keys.

  2. In Android, Cipher.getInstance("RSA") defaults to Cipher.getInstance("RSA/ECB/NoPadding"), but Oracle Java defaults to Cipher.getInstance("RSA/ECB/PKCS1Padding")






share|improve this answer


























  • I have just checked on 4th Android and the last. Runtime is still working. So I dont think that the reason in versions

    – Kirill Matrosov
    Nov 22 '18 at 16:49











  • I will try to experiment with your code but I'm not a Kotlin programmer.

    – James K Polk
    Nov 22 '18 at 17:07











  • It helped. But I still dont understand why the same code works in runtime and doesnt work while testing

    – Kirill Matrosov
    Nov 23 '18 at 8:52






  • 1





    I'll add that info to the answer. Let me know if it still remains unclear.

    – James K Polk
    Nov 23 '18 at 14:16














1












1








1







The issue is that the private key is not a PKCS8EncodedKeySpec, but rather an RSAPrivateKey object from PKCS#1. The BC provider, however, will still decode this mistake without complaint. However, other providers will rightfully complain. My guess is that the runtime is using an older version of Android where the default provider is BC, but your test is using a newer version where that isn't the case.



The fix is to make your private key a proper PKCS8EncodedKeySpec. Alternatively, you can explicitly request the "BC" provider. To do so, you need to specify "BC" in the getInstance() call: val keyFactory = KeyFactory.getInstance("RSA", "BC")



However, note that it appears that BC provider support is on its way out.



To convert a private key in the PKCS#1 format, either wrap a 'BEGIN RSA PRIVATE KEY'-style header and footer around the base64 blob or decode the base64 blob and place that in a file, then run:



openssl pkcs8 -topk8 -in privkey.pem  -outform der -nocrypt | openssl base64 -A


or



openssl pkcs8 -topk8 -in privkey.der -inform der -nocrypt  | openssl base64 -A


A second issue comes from relying on defaults. Instead of doing



val c = Cipher.getInstance("RSA")


which gets you defaults for mode and padding and thus is non-portable, always specify the full "algorithm/mode/padding" transformation string to Cipher.getInstance(). In you case, it appears the data is not padded (an insecure mode) you'd need something like



val c = Cipher.getInstance("RSA/ECB/NoPadding")


However, you really should use proper randomized padding, and currently that is OAEP padding.



Summary



The runtime environment is Android, but I think the test environment is Oracle Java (or maybe openjdk). There are evidently two critical differences in those environments:




  1. Android uses the BC provider for KeyFactory which will handle private keys encoded in PKCS#1 RSAPrivateKey format. Oracle Java only supports PKCS8 encoded keys.

  2. In Android, Cipher.getInstance("RSA") defaults to Cipher.getInstance("RSA/ECB/NoPadding"), but Oracle Java defaults to Cipher.getInstance("RSA/ECB/PKCS1Padding")






share|improve this answer















The issue is that the private key is not a PKCS8EncodedKeySpec, but rather an RSAPrivateKey object from PKCS#1. The BC provider, however, will still decode this mistake without complaint. However, other providers will rightfully complain. My guess is that the runtime is using an older version of Android where the default provider is BC, but your test is using a newer version where that isn't the case.



The fix is to make your private key a proper PKCS8EncodedKeySpec. Alternatively, you can explicitly request the "BC" provider. To do so, you need to specify "BC" in the getInstance() call: val keyFactory = KeyFactory.getInstance("RSA", "BC")



However, note that it appears that BC provider support is on its way out.



To convert a private key in the PKCS#1 format, either wrap a 'BEGIN RSA PRIVATE KEY'-style header and footer around the base64 blob or decode the base64 blob and place that in a file, then run:



openssl pkcs8 -topk8 -in privkey.pem  -outform der -nocrypt | openssl base64 -A


or



openssl pkcs8 -topk8 -in privkey.der -inform der -nocrypt  | openssl base64 -A


A second issue comes from relying on defaults. Instead of doing



val c = Cipher.getInstance("RSA")


which gets you defaults for mode and padding and thus is non-portable, always specify the full "algorithm/mode/padding" transformation string to Cipher.getInstance(). In you case, it appears the data is not padded (an insecure mode) you'd need something like



val c = Cipher.getInstance("RSA/ECB/NoPadding")


However, you really should use proper randomized padding, and currently that is OAEP padding.



Summary



The runtime environment is Android, but I think the test environment is Oracle Java (or maybe openjdk). There are evidently two critical differences in those environments:




  1. Android uses the BC provider for KeyFactory which will handle private keys encoded in PKCS#1 RSAPrivateKey format. Oracle Java only supports PKCS8 encoded keys.

  2. In Android, Cipher.getInstance("RSA") defaults to Cipher.getInstance("RSA/ECB/NoPadding"), but Oracle Java defaults to Cipher.getInstance("RSA/ECB/PKCS1Padding")







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 23 '18 at 14:26

























answered Nov 22 '18 at 16:44









James K PolkJames K Polk

30.6k116997




30.6k116997













  • I have just checked on 4th Android and the last. Runtime is still working. So I dont think that the reason in versions

    – Kirill Matrosov
    Nov 22 '18 at 16:49











  • I will try to experiment with your code but I'm not a Kotlin programmer.

    – James K Polk
    Nov 22 '18 at 17:07











  • It helped. But I still dont understand why the same code works in runtime and doesnt work while testing

    – Kirill Matrosov
    Nov 23 '18 at 8:52






  • 1





    I'll add that info to the answer. Let me know if it still remains unclear.

    – James K Polk
    Nov 23 '18 at 14:16



















  • I have just checked on 4th Android and the last. Runtime is still working. So I dont think that the reason in versions

    – Kirill Matrosov
    Nov 22 '18 at 16:49











  • I will try to experiment with your code but I'm not a Kotlin programmer.

    – James K Polk
    Nov 22 '18 at 17:07











  • It helped. But I still dont understand why the same code works in runtime and doesnt work while testing

    – Kirill Matrosov
    Nov 23 '18 at 8:52






  • 1





    I'll add that info to the answer. Let me know if it still remains unclear.

    – James K Polk
    Nov 23 '18 at 14:16

















I have just checked on 4th Android and the last. Runtime is still working. So I dont think that the reason in versions

– Kirill Matrosov
Nov 22 '18 at 16:49





I have just checked on 4th Android and the last. Runtime is still working. So I dont think that the reason in versions

– Kirill Matrosov
Nov 22 '18 at 16:49













I will try to experiment with your code but I'm not a Kotlin programmer.

– James K Polk
Nov 22 '18 at 17:07





I will try to experiment with your code but I'm not a Kotlin programmer.

– James K Polk
Nov 22 '18 at 17:07













It helped. But I still dont understand why the same code works in runtime and doesnt work while testing

– Kirill Matrosov
Nov 23 '18 at 8:52





It helped. But I still dont understand why the same code works in runtime and doesnt work while testing

– Kirill Matrosov
Nov 23 '18 at 8:52




1




1





I'll add that info to the answer. Let me know if it still remains unclear.

– James K Polk
Nov 23 '18 at 14:16





I'll add that info to the answer. Let me know if it still remains unclear.

– James K Polk
Nov 23 '18 at 14:16




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435000%2fdifferent-codes-behavior-in-unit-test-and-in-runtime%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to change which sound is reproduced for terminal bell?

Can I use Tabulator js library in my java Spring + Thymeleaf project?

Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents