Wrzucam jako ciekawostkę:
import org.junit.jupiter.api.Assertions.assertEquals
import kotlin.test.Test
import kotlin.test.assertTrue
internal class MainKtTest {
@Test
fun passwordToPrivateKeyTest() {
val key1 = passwordToPrivateKeyBC("password")
val key2 = passwordToPrivateKeyBC("password")
assertEquals(key1, key2)
}
@Test
fun generateSignVerify() {
val password = "password"
val privateKey = passwordToPrivateKeyBC(password)
val message = "This is message to sign and verify"
val sign = sign(privateKey, message)
val verificationResult = verify(privateKeyToPublicKey(privateKey), message, sign[0], sign[1])
assertTrue(verificationResult)
}
}
i sam kod:
import org.bouncycastle.asn1.sec.ECPrivateKey
import org.bouncycastle.asn1.sec.SECNamedCurves
import org.bouncycastle.crypto.digests.SHA256Digest
import org.bouncycastle.crypto.params.ECDomainParameters
import org.bouncycastle.crypto.params.ECPrivateKeyParameters
import org.bouncycastle.crypto.params.ECPublicKeyParameters
import org.bouncycastle.crypto.signers.ECDSASigner
import org.bouncycastle.crypto.signers.HMacDSAKCalculator
import org.bouncycastle.math.ec.ECPoint
import java.math.BigInteger
import java.security.MessageDigest
fun passwordToPrivateKeyBC(password: String): ECPrivateKey {
val passwordDigest = MessageDigest.getInstance("SHA-256").digest(password.toByteArray())
val d = BigInteger(passwordDigest)
return ECPrivateKey(256, d)
}
private const val CURVE = "secp256k1"
fun privateKeyToPublicKey(privateKey: ECPrivateKey): ECPoint {
val curve = SECNamedCurves.getByName(CURVE)
return curve.g.multiply(privateKey.key)
}
fun sign(privateKey: ECPrivateKey, textToSing: String): Array<out BigInteger> {
val signer = ECDSASigner(HMacDSAKCalculator(SHA256Digest()))
val privateKeyParams = ECPrivateKeyParameters(privateKey.key, ECDomainParameters(SECNamedCurves.getByName(CURVE)))
signer.init(true, privateKeyParams)
return signer.generateSignature(textToSing.toByteArray())
}
fun verify(publicKey: ECPoint, message: String, r: BigInteger, s: BigInteger): Boolean {
val ecDomainParameters: ECDomainParameters = ECDomainParameters(SECNamedCurves.getByName(CURVE))
val ecPublicKeyParameters = ECPublicKeyParameters(publicKey, ecDomainParameters)
val signer = ECDSASigner()
signer.init(false, ecPublicKeyParameters)
return signer.verifySignature(message.toByteArray(), r, s)
}