Error : ```java.lang.IllegalStateException: No pro...
# multiplatform
h
Error :
Copy code
java.lang.IllegalStateException: No providers registered. Please provide a dependency or register provider explicitly
Sample code :
Copy code
fun encrypt(plainText: String): ByteArray =
        runBlocking {
            CryptographyProvider.Default
                .get(SHA512)
                .hasher()
                .hash(plainText.encodeToByteArray())
        }
library use:
Copy code
dev.whyoleg.cryptography
how to solve this problem
m
Not familiar with that lib. Buy, may I interest you, in changing the used lib to https://github.com/KotlinCrypto/hash and if you need HMac you can use https://github.com/KotlinCrypto/MACs
h
@Moussa is there any tutorial on how to use it?
m
The readme file of the repo, have a great explanation
For your specific example, in gradle you would import this in
commonMain
Copy code
// SHA-224, SHA-256, SHA-384, SHA-512
// SHA-512/t, SHA-512/224, SHA-512/256
implementation("org.kotlincrypto.hash:sha2:0.6.0")
Then in method implementation would be
Copy code
fun encrypt(plainText: String): ByteArray =
    runBlocking {
        val hasher = SHA256()
        val hashedByteArrray = hasher.digest(plainText.encodeToByteArray())
        
    }
h
@Moussa instead of return byteArray as encrypted, is there way to get hash key string ?
m
If you mean making the hashed value to a string, you would use an encoding like Base64 encoding If you are using Kotlin 1.8 or above you can use their implementation of it like so
Copy code
Base64.Default.withPadding(Base64.PaddingOption.PRESENT).encode(hashedByteArray)
h
@Moussa how to decode back after encode?
m
Using the following
Copy code
Base64.Default.withPadding(Base64.PaddingOption.PRESENT).decode(encodedData)
Where
encodedData
is the Base64 encoded String which will return a
ByteArray
which in your example would be the
hashedByteArrray
h
Copy code
Base64.Default.withPadding(Base64.PaddingOption.PRESENT).decode(encoded).decodeToString()
is that correct?
i try it not return to original string that i want
encodeBaseUrl: LGpwd/P9L/6cFEQsxLR3kLnkPKtazPjXEpL8UBCvV1A= decodeBaseUrl: ,jpw��/��D,Ĵw���<�Z�����P�WP this is what i get?
m
If the original value is normal String, yes that would work example
Copy code
val plainText: String = "Hello World!"
val encodedData = Base64.Default.withPadding(Base64.PaddingOption.PRESENT).encode(plainText)
val decodedData = Base64.Default.withPadding(Base64.PaddingOption.PRESENT).decode(encodedData).decodeToString() // returns "Hello World!" which is `plainText`
But, in your case, it is the result of a
hash
which means it is the
ByteArray
representation of the
hash
which should not be converted to a normal
string
it should be encoded with something like
Base64
encoding. example
Copy code
// NOTE: hash is a one way cryptography, there is no mathematical decryption of a hash. 
// NOTE: every time you give the same `plainText` to the same `hash` you will get the same value.
// This method will hash the `plainText` and return the hashed value.
fun sha256Hash(plainText: String): ByteArray =
    runBlocking {
        val hasher = SHA256()
        val hashedByteArrray = hasher.digest(plainText.encodeToByteArray())
        return hashedByteArrray
    }

// This method will hash the given `plainText` then encode it in Base64 encoding and return it.
fun sha256HashEncodingBase64(plainText: String): String =
    runBlocking {
        val hasher = SHA256()
        val hashedByteArrray = hasher.digest(plainText.encodeToByteArray())
        val base64Encoded = Base64.Default.withPadding(Base64.PaddingOption.PRESENT).encode(hashedByteArray)
        return base64Encoded
    }
Using
sha256HashEncodingBase64
method will return a
Base64
encoding string of the hashed value. If you want to verify an existing hash value, you would need 3 things: • The hashed value • The plain text value • The used hash method (In you case the hash method is
SHA256
)
Copy code
// This method takes the plaintext and the hashed byte array which in this example the result of `sha256Hash` method.
fun verifySha256(plainText: String, hashedByteArrray: ByteArray): Boolean {
    val hashed = sha256Hash(plainText)
    return hashedByteArrray.contentEquals(hashed)
}

// This method takes the plaintext and the encoded hashed byte array which in this example the result of `sha256HashEncodingBase64` method.
fun verifySha256(plainText: String, encodedHashed: String): Boolean {
    val encoded = sha256HashEncodingBase64(plainText)
    return encoded == encodedHashed
}
h
so conclude that hashkey/hashbyteArray can't return to plaintext decode unless for checking hashkey isn't? in this case i have to use normal String 64bit, but does it is secure?
m
• When you say,
hashkey
, what do you mean? • Also, it would be very helpful for me in order to better help you if I understood you use case or at least have a better understanding of what you are trying to accomplish so I can better help you.
h
what i want to accomplish : 1. turn plaintext -> hashedByteArray -> 64encode->stringEncoding 2. then, stringEncoding->64decode->hashedByteArray->plaintext this is what i want.
m
So, hashing is like creating a digital fingerprint for any piece of data – a text, a file, anything! You use a special function (the "hash function", for the sake of the current thread it is
SHA256
) that scrambles the data into a short, fixed-size string of characters, the "hash". There is no way to convert the hashed value to it's plain text. For that, you would use an Encryption like
AES
encryption.
h
Encryption like
AES
encryption do you have example of it? thanks
m
unfortunately I don't know of a lib that provides
AES
. But, you can use the
expect/actual
feature in KMP to have a method for encryption and another one for decryption and you can implement the platform logic using their existing cryptography modules
👍 1