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;
}
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
|
show 1 more comment
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
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
|
show 1 more comment
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
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
android kotlin
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
|
show 1 more comment
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
|
show 1 more comment
1 Answer
1
active
oldest
votes
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:
- 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.
- In Android,
Cipher.getInstance("RSA")
defaults toCipher.getInstance("RSA/ECB/NoPadding")
, but Oracle Java defaults toCipher.getInstance("RSA/ECB/PKCS1Padding")
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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:
- 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.
- In Android,
Cipher.getInstance("RSA")
defaults toCipher.getInstance("RSA/ECB/NoPadding")
, but Oracle Java defaults toCipher.getInstance("RSA/ECB/PKCS1Padding")
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
add a comment |
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:
- 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.
- In Android,
Cipher.getInstance("RSA")
defaults toCipher.getInstance("RSA/ECB/NoPadding")
, but Oracle Java defaults toCipher.getInstance("RSA/ECB/PKCS1Padding")
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
add a comment |
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:
- 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.
- In Android,
Cipher.getInstance("RSA")
defaults toCipher.getInstance("RSA/ECB/NoPadding")
, but Oracle Java defaults toCipher.getInstance("RSA/ECB/PKCS1Padding")
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:
- 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.
- In Android,
Cipher.getInstance("RSA")
defaults toCipher.getInstance("RSA/ECB/NoPadding")
, but Oracle Java defaults toCipher.getInstance("RSA/ECB/PKCS1Padding")
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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