Updated on 2026-08-14

This commit is contained in:
Tangem 2020-03-30 20:09:57 +03:00
parent 0ad47fca68
commit 5f7612ca57
4 changed files with 60 additions and 14 deletions

View file

@ -262,14 +262,12 @@ class CardManager(
* during personalization.
* @param cardId this parameter will set up CID, Unique Tangem card ID.
*/
fun personalize(config: CardConfig,
cardId: String,
callback: (result: TaskEvent<Card>) -> Unit) {
fun personalize(config: CardConfig, callback: (result: TaskEvent<Card>) -> Unit) {
if (this.config.issuer == null) {
callback(TaskEvent.Completion(TaskError.IssuerIsRequired()))
return
}
val personalizationCommand = PersonalizeCommand(config, cardId)
val personalizationCommand = PersonalizeCommand(config)
val task = SingleCommandTask(personalizationCommand)
task.performPreflightRead = false
runTask(task, callback = callback)

View file

@ -4,6 +4,7 @@ import com.tangem.commands.Card
import com.tangem.commands.CardData
import com.tangem.commands.CommandSerializer
import com.tangem.commands.personalization.entities.Issuer
import com.tangem.commands.personalization.util.CardIdCreator
import com.tangem.common.CardEnvironment
import com.tangem.common.apdu.CommandApdu
import com.tangem.common.apdu.Instruction
@ -27,7 +28,7 @@ import com.tangem.tasks.TaskError
* during personalization.
* @param cardId this parameter will set up CID, Unique Tangem card ID.
*/
class PersonalizeCommand(private val config: CardConfig, private val cardId: String) : CommandSerializer<Card>() {
class PersonalizeCommand(private val config: CardConfig) : CommandSerializer<Card>() {
override fun serialize(cardEnvironment: CardEnvironment): CommandApdu {
if (cardEnvironment.issuer == null || cardEnvironment.manufacturerKeyPair == null) {
@ -36,9 +37,8 @@ class PersonalizeCommand(private val config: CardConfig, private val cardId: Str
return CommandApdu(
Instruction.Personalize,
serializePersonalizationData(
cardId, config,
cardEnvironment.issuer, cardEnvironment.manufacturerKeyPair.privateKey,
cardEnvironment.acquirerKeyPair?.publicKey),
config, cardEnvironment.issuer,
cardEnvironment.manufacturerKeyPair.privateKey, cardEnvironment.acquirerKeyPair?.publicKey),
encryptionKey = devPersonalizationKey
)
}
@ -99,13 +99,14 @@ class PersonalizeCommand(private val config: CardConfig, private val cardId: Str
)
}
private fun serializePersonalizationData(cardId: String, config: CardConfig,
issuer: Issuer, manufacturerPrivateKey: ByteArray,
private fun serializePersonalizationData(config: CardConfig, issuer: Issuer,
manufacturerPrivateKey: ByteArray,
acquirePublicKey: ByteArray?
): ByteArray {
val cardId = CardIdCreator.create(config.series, config.startNumber)
?: throw TaskError.SerializeCommandError()
val tlvBuilder = TlvBuilder()
tlvBuilder.append(TlvTag.CardId, cardId)
tlvBuilder.append(TlvTag.CurveId, config.curveID)
tlvBuilder.append(TlvTag.MaxSignatures, config.maxSignatures)
tlvBuilder.append(TlvTag.SigningMethod, config.signingMethod)

View file

@ -0,0 +1,49 @@
package com.tangem.commands.personalization.util
/**
[REDACTED_AUTHOR]
*/
internal class CardIdCreator {
companion object {
private val Alf = "ABCDEF0123456789"
fun create(nsSeries: String?, number: Long): String? {
val series = nsSeries ?: return null
if (number <= 0 || (series.length != 2 && series.length != 4)) return null
if (!checkSeries(series)) return null
val tail = if (series.length == 2) String.format("%013d", number) else String.format("%011d", number)
val cardId = series + tail
return completeCardID(cardId)
}
private fun checkSeries(series: String): Boolean {
val containsList = series.filter { Alf.contains(it) }
return containsList.length == series.length
}
private fun completeCardID(imCardId: String): String? {
var cardId = imCardId
cardId = cardId.replace(" ", "")
if (cardId.length != 15 || Alf.indexOf(cardId[0]) == -1 || Alf.indexOf(cardId[1]) == -1)
return null
cardId += "0"
val length = cardId.length
var sum = 0
for (i in 0 until length) {
// get digits in reverse order
var digit: Int
val cDigit = cardId[length - i - 1]
digit = if (cDigit in '0'..'9') cDigit - '0' else cDigit - 'A'
// every 2nd number multiply with 2
if (i % 2 == 1) digit *= 2
sum += if (digit > 9) digit - 9 else digit
}
val lunh = (10 - sum % 10) % 10
return cardId.substring(0, 15) + String.format("%d", lunh)
}
}
}

View file

@ -154,9 +154,7 @@ class MainActivity : AppCompatActivity() {
}
btn_read_write_user_data?.setOnClickListener { startActivity(Intent(this, TestUserDataActivity::class.java)) }
btn_personalize?.setOnClickListener { _ ->
cardManager.personalize(
CardConfig.init(application), "BB00000000000395"
) {
cardManager.personalize(CardConfig.init(application)) {
when (it) {
is TaskEvent.Completion -> {
if (it.error != null) runOnUiThread { tv_card_cid?.text = it.error!!::class.simpleName }