I have some source code in Kotlin that I only partially understand. I know a little bit of Python so I'm looking to recreate the decrypt function.
I have an encrypted string that I want to recover, and the original passphrase and salt too.
Here is the source (from here, with constants, encrypt function etc):
fun decrypt(passPhrase: String, salt: ByteArray, encryptedData: String): String? {
val iv: ByteArray?
val encrypted: ByteArray?
return try {
lastException = null
val byteBuffer = ByteBuffer.wrap(Base64.decode(encryptedData))
val ivLength = byteBuffer.get().toInt()
iv = ByteArray(ivLength)
byteBuffer[iv]
encrypted = ByteArray(byteBuffer.remaining())
byteBuffer[encrypted]
val cipherDec: Cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipherDec.init(Cipher.DECRYPT_MODE, prepCipherKey(passPhrase, salt), GCMParameterSpec(TAG_LENGTH_BIT, iv))
val dec = cipherDec.doFinal(encrypted)
String(dec)
} catch (e: Exception) {
lastException = e
aapsLogger.error("Decryption failed due to technical exception: $e")
null
}
}
Here is my attempt simplified (I get incorrect padding when using the inputs I have):
def generate_key(password, salt, iterations):
assert iterations > 0
key = base64.b64decode(password + salt)
for i in range(iterations):
key = hashlib.sha256(key).digest()
return key
def decrypt(ciphertext, password):
salt = 'XXXXXXXetc'
key = generate_key(password, salt, NUMBER_OF_ITERATIONS)
cipher = AES.new(key, AES.MODE_GCM)
plaintext = decrypt(ciphertext, cipher)
return plaintext
Edit:
Here is some test data, with passphrase 1234
{
"format": "aaps_encrypted",
"metadata": {
"device_name": "Galaxy S8 SE",
"created_at": "2022-04-19T19:58:17.338Z",
"aaps_version": "3.0.0.1",
"aaps_flavour": "full",
"device_model": "samsung SM-G950F (dreamlte)"
},
"security": {
"file_hash": "96cf809f37eb46d0eb837511bae539b5fadd424e74d3e6eedaa4ceb2fdac07d8",
"algorithm": "v1",
"salt": "4030cc7f15e5f7bf830543270ced2b7c8b24237c53ce95382b232df69c594353",
"content_hash": "197510b071e3e592c43301e77c997400048641e77275a02ebd41a58213e90c61"
},
"content": "DKQDMzcfTQdd59fKSN5s3pmcbs+nK4fS6VUt0+sfWDolkrUqfq33HT82GOpUwCpCtHH0zwY2plw8ZEgv1a4I\/OjDQeueAyVL8NZUiNKWPdtUwSxbfiAuP6P61H1X9iGIAvhuvR+uyy2l\/DNyWqIox2tvcNGXqt3og2mFojiqryB+tKfia8dO7bpph\/8q3\/NGtJajijqTPNCcjLid8N0yivEXKSXaceL9qdGGZNoMGmIGMhrlrS8JBKOfRvFkE7hdat6D8uaF4iyxfuLGY210oDenf2V+GcT5XBWv8nr1NKWaQTJOLx6A2QKZM\/9xKck0fl04PCFFz+d0x+Y3HgiecFrU3uCWKSL901OCUIlDdOiR7U1Ik1BJFfRzZMaB8qLU7uyc9SNzXs55u3Xm2yD14Fa44jhQKkXI\/DplqYl4M8wgSL7M2oCqNIMI4VpRpRF9apGRcdzVCjwnOWk3mBQkOUn\/etITu2kRMB8QZqvxXJtW40ZRjmqNXH7\/xWV+jDr+3QnmdvqVl7YvityxfPmTTnJdQpUYvV8SbKR2kclidhZ9pTF14yndejNrZru5IE5D7a8vuiydkL6vcAchM9ts3MBv\/lg0Bu5y8H5+DCp8lwVBZDgPnjH1CpfNtk\/nYTJnlkkmRdjozZeqjrC8J\/+saRqizgXFqblVXY2A3Z0gF9iVjbGZywsabns1vUuYalqaXKW9U8sNZvs3S0\/ngRC25Rgo6AQdloqKr4PLeCEO18jq\/Vh+Vky8MoAZXS\/xmCyFdAn+EDLCdhKEYTA9Ynl+pRTGAwtS9HLgNq36AohlKQm2vuRP1dchaelzL5tycHuNQq6zqUqh+4j0dw2vd7P8ZRvE3m5wNnOLC7lugpddxnbrwI\/j1Pu9aPlHHZWTy9dKW01IThVC9FWJqnhEhGao19FDXBEAjOUh70o2YIDb3d8oEDLMJX5Weaaoh9itMVLkafwmYx3YhqZqZ+38RykuL7x36aCksefL\/YtphPJkxwPgny2IDM6948uNUg3jUCem7ZwxHTWhgsIxI00PNo2D1ZWAOdk8HPy+gRaJ\/rXsNvo0ErW2CD4gkKT8cvwkRJ2WH+ovcVrcMFO1Ns7a8VdksjuMZhCWa8rzl6efRznT7FkXrKJSmUG5WkLQbPlSirMN2YK2R111qm7hbxvcTMFvGIh6ZZDHdDaaWMi7M3nHRT8AzlTiap1arnTCpSqtMVndB4Gu6i\/fNOFiV+3iXFfDUJsgvcGBDHsOQZ3lCdkHcCz5H1UB8D0tqqPHKt\/TAAwz\/Ew5axshAmiCuKqC+EiTTHkHKd1e5uCF5kRXJWxlzlGNWYJmVZOkPfDpV0mX81Nc9RGgAKnzZ9v\/kHvzKsCjXyPbgzXBuYB+FqaaP8CNNlyrKuTObqndUnCPIbIpBEtMf7auI2n5ME78KXd+fPX1PvCYx3z4Z6FwZVBNtfTiIQgK4obNaPG40ysdcSGonKSDEVNEUDlZOZWTdNxGfXa5XfmsYN+qw3v1+Sd2FDKjlP1BZPOmsCNEWXBrnqLsuoHnGv20che\/spEsS8aTQ4pWCerb4f7o13b303cTbSyQaC0AohH9UfjdXS19pkdHQySV2EXTLfcvfPPX+E39aZG4BiKZ86jbmUQNjhgpoFupK9VUa7ZEEwQfhUOrTvZr+zcwV0fJcD9FaaEcVLs1kez7TRhS\/p8rBUpSvoLa5KSEfquHbQq0WUr\/bSiX0hXVGY0h6MooZ8z\/HCFzzBHhHFZfRfsEbr1F9cJp7cn8MuqDuIH3GJ+6wW8JAb\/ftk\/BHMtfSvT\/TWxmldn+Z5GQwGODJ5nGQTzsFmOJszSoVubVfuEJQ94SMHAB0tULDHhIFDknDgDjEY3VuNQ51ZC8nGas4XuohLTMeZ6cmJJmTnvPYDFb0RlbVrG7TVq7VaoZNIx9tTUhmAaSvbiiDc9pHGbiWAb5oe9dpGWjPDi5kayrckDjWkImy3jJLEV+s9Dtz5R621+GzkQYw0KTKDEaqQtVkWXPP+8do2PyRn+zh5MOpV7CxVKbjs19vR2gcC2DE9Ra\/naK+cvKiwLnzmZEleBCCKsB5+9LJzHvhPrpbaFczKxDi\/A9LAwCFawGjsS6hF58tI2FpZoOw\/FacP1wb8V6sp97dCZjRH14ECMp24AuTfnmbwXmabT5\/zJUyDZoGCd7NONM0lOFBDFmKn+kwo\/gyB5Sy\/YFFVEeTEfzL+49tPfphA\/SmbeyCop51ln8BeIOTTpdAwhSNpyU2YzUB845nN6I+\/9QUO7ErkHBEhbAbwbVAiLev0dkw9J+2V4tZEMVzhoJrV5QjBiu+wvGj0pBUhmSXOUhfyqnlp3XK6FU7M63MWzRlkZarW7FFHcGdhnArqQ9st\/ETdVXGpVR3ZGPxeh0C9ycjUpPKtRxEuNf93JGf99UPxou83zoL3sfEkxfWAbDB0eW2WoNZveuPaLwN3fGEgQaxglEXlM\/L9CaihvCZocseWHtpoBS1HjdHj7gGrRF\/DPOudS8dvu\/mWmK4IaUKIErYZoBnjopDmtpzqoNENjTNkhRvp3ojxg\/DgXsos3t7RxORC07T0SC\/SjUo6veEk5COlLENb49PozZbVIL6YECXp1xJxbf\/QCFiXosA+S34ERwSwkJGYGhaPY42XJUODplYecy22FKjg2HN\/bvR213IQt9ctmZN5JB3wC8Fmyi5faxf2sl9VV3aM7ekpr3tyj7ATAvyRMl1UlnAz30ZO7GGhGhQbxYpe5SU20dpcVfC+U3VQzrsGHW5f6OaI3GJpM5PVL98bK+CfXEvC9acmPyH0AVHPWvYPEih81r2Ek4n2T6evtgrvixbRBGDTr24hB+27u29GEsZnqoL9vPx7xJeJ1WYYKYerVg+t2GiVgEmn3XOFt3CkrSrp144HrWo0ZgAipTQ8BHVJ45r5WsojRLKrazpJMYLnFBSx4iokhtODb9dv0Tum+wZ2zUIhsXDMBbAsjSDhJtrQLwuCoLzaz7o5BGinq9fIJks7uVZ5dUGe5dMJux8zNwujPVP9fuwsmmP6ObbGsG4MEhgyVoSpV39v8l7gyrulLp3D1fxbtNmZ9JolHFNtGTrkbouFjEnKn8B4iE4ofLGcuWGBnw\/zVSerFdMO8\/I4FaofLFQCLmx92s\/ROBXuycYJ4Isa4flJAwWK8SKIFpGWQg\/FfLkij611I+1i5m8wHX2XHcm5veA4ZcdcfhzqtywP8onLia0KZdZMrRRwa4oz6wumV3m56tyS\/zeEiPri9iqitZnlVwEtHCh\/jTQwfUykbMiidVficpqPGi5k8D0iUTJ5FtFSQkVOpK9KOX7CgO\/z6958d\/ZA9SJ1XZumuTBDfFmOwI3nkOIbThjGfvs7OlHyxP6K6k3Jkygt8bLUIshJHwLOPRlFlNhZLN9mcIYRhdVMJr0ZODLjdTLB94gLYUTffsLc27JHVeBEWWtDBr8IEc3Oq7cqPZpbSTM1\/5pjlxRXYIUIlgeAbUMeg\/yHof6NyPpzjO1bxhj1YM4qmnWL34f82eO\/3sim5GcT56hm5pkFeF2vKs+JKbVNYwaMOYhcuQBCXT+Ta+hqCjColVQrJf9twy1k+aGkJrMBaKelIYaWprKGennWL\/hVQwEgOR28426euRTHdgWPsQqe46hy1FabEjiWgRYsSiIwKHszpKXEyy760BvJqeJhRC4FFDooD8grnjuoDpnK8brUhlwWlmpPDSbm02eZSPxT54zBkti5u\/EONG2Dj3EtQ6jaQ29CvxVkIHPwapyTWBMO3d4dGJ0pfhYVHLwxtd02I8eVBU471jv57cU\/P4ypYGLMt3q14MMfKVTKqSbE0lM0mVt1wPgRTolIsAbRJYdDuwrQXxFM0mo1SXjkAwdoXxlYwBnLT6rsLwQpI0VrkESygdFjuWrc\/1IDbUkoy99nlC7YmQ9drvR6h7Jhol2LuQPche+fnIy4rzx6XD6K1GFwa5Rii\/pBCvJ4AH9z3EwKhvL1Q0U1SjUiKTv69OSWfQKmjFLehtRrXx8odVFiYafxhfsskstPDkbdElT5SvLUOZOrqqdHq78LJuLC7GBRd1OPTG0VpokmSGNigRAwV+ZvlY8D\/Xqlyc92FCnl9auQGsfwmcvcgiM74YcRTKFfH4sHmIPgWxBH3\/oX5S9fn40hOORHMpQwqpdD+IvMiVS1dgKfThNT39JaMu441THkPH9ijYLJdlUv+SVtiMqnk+rZXgNsSeWSkhduGKs22wXceFM1CWIZtlvM6VL\/n8tHaOF0hk1F5GJ1kSbAG97YG8dRTU9XvcOzyStCYw1yDGH0Wo0V8iLyPefBNbueFpPcnkQ9sAt9fhDx+v4XJ6X9Vq0iNvGbZQWo8wZghAOjMPNiopJUuL4hky4rXxrp0o5uCtNJSvmgs8FUUD8Wjn5\/9ZMA4EXNvmNBxSrpifiwWx+Hrq9tUD22uFb\/8Y5BWHjSNUOeed1QG9upxKf6FXPohfDVd1Y7ECNh7J12yvrFkxo+PiUDlyC47OKzc4NlYZMZLLA4udHln4aAXEnwRm6tmK0tKbbTWkjsgWrQChT\/Soxv4a\/vqjqvwLzm1grr2iaYSYAOMRDMwRse\/h9L913RKI9+IbmRfToxgTcrSqIhBDM99H+PARRIBZtf75dEOn4yGBqEMyroPgR0mjs2dPslMOntIPYbLAUoAKydpc0FNbvmpmaX5n0N1dFB3UJZOFYKP+A5nx8kYWsKhG+nfjvMVPF7eFW7YksQfWqT8xka33ySfWhdPbtbyNWXJxKUCZSzzorc4qHQuo5GQCO3Tu\/V4TTfNENcxgE3VZDQ0qUPix4ShIx5WDn7uYtj8oP+jWuqbwu+blV45w\/u8\/yAbR5HWDfY5n3ce3yeqPlaX50jZ5iBWdY27LtYwy+R79cgxL+x\/hMMmftKoz1e5UL33JJ+Aq+clbjUSKkSK7lpuJDhCUb2MXi0jy2KkyHfP5vPcdcuqLCwc\/UPRrxjsYfIQDzryGHXbX2RoFPINnZU0uqOm2YuHz9+9zEX1ahpTKTx0y2j7OdsD2PBAJs1a8ip9j4Xx+7ZNM6Ngqvsm2cAjurtcp52yCkIuDOoVU6t5OBwCbm6SRQswT1oayjEgbUn\/Kn6+oXDrx9Vc4G\/hZk95kK1Ygu6Sh1PEeftTNXVfYkpfjRgb0UQDPpupDL83cEKC+WhSp\/3S2sMo8tUtENPX9EXO+nLEy6XZEA1FpalN6vT4ThMYUximQEGXb\/fYerhaC353Ht\/f5Dr56KGuwDPCSpL4yJJ6BloU2qgxwZiIHp8IM86k1bnMuCnY3KZltvPcXXJ6E5sDQB0Z1BLnnSnLKuAKeX6ulJ5noBkTzZe4rQwHF5cXNQx9pX6TFKxjSiu9qAB9fQYrm6Faj8FqbTVhACKSXHw7kj3DOeavgE28wyj9pO\/jfGfwV8sP3xOH1r4pM6CbuJavgXticH0X9ho6VyrRrsy74XZp1AI6FBHP6iIdA\/b7w7il8Vl7TsaZyf+xbYtCM1hIcsgCUVo50tYG3CoL+5kOjfzViZnxlJZhEGqZssp+\/kOb7Ty2ZoS0ZewjqRwOesRdEFM2ABy43qLuT7C1ulOJgYxKkAh4leb3vd0HYIXXTEkbfxrhHQ9j2dB3by6OyPbPgw8dVojeSAL\/7\/zaJoJdApKfeiV8BCHgsNdrdoVonOH4an0SD3YVuB5Yz81Z2C43WEJIUBITL\/RVnVLIGOxVmEWHD4FkwQPgmUS770Z8rqq2sZRUIGgYgKSeAGkslE4itJUQ+\/LeFwbK3WYaVa8iT4Rd74goc7Dm39h54qZ6dgel0CqgvzAngw2NmTP3aETa\/Co+eMwNyCLP+QxGEzcnqgcs63YQyqrtG4pVhQg5cMkQbRpqsytHPjg2mS+fBSAD1sXF5lrThlg6skL70o4H36abbAjOST\/ThvJ\/hViFb6lCD7w+iXDuOa0+p3sn4yhgMIqcRwKjcIxx5GsGNNSJDKWWJn7zxdT525gwSh7rf\/aGVI9PNUhlXC0bdcHQ4UjIkqSa5MQbapiDDhg1PEqDlBa0v6vqSIdDAKaxWVZNYk0Msr3cNwaAYyQfdYVCrd6CN0bFIeOWOng6klQhTYxkhmrsogCXCsMLDFaBr\/IbfQSMfwtsYiM9Jtcn18QjfumXucfKL\/F0rP0D3FKOD72idANPCy+73lYAxGSDLVmT4wmsGCEcmAtrJHCauHn65T+lSZ5d8LGFbU4P3fzP2i0+vDfPh74\/BOpx3rPgJ24chryugVZ3LRgCYrphkiiz7u+cAAsUUmcb3\/9Oy8hRdqMYIW+d8bvLygwdt\/5BjGALaF4l6kr+BuC3Zdfm3VpNgSd0yneWc81sHJVY+NTGGH6r0UEGlNOaXfv3EgCVKFIVVxQ7sdQZMlVsh\/st7NET6aPvEALHnfcC1LxmnBq4eDHNPD9Dkf2BPedenQM+nl1kzvFAn3wmRknOkW5R1yNn\/ytxx0HGmmR8Ice5wgZ4O1iiu6gYQIgfNh7iqZa6f9+uRR7OPx3G3F3FqU494Fz966O311NQWt0v9OsZcTCjdHJacQQAlrhj6ueuAjvzwPEONSf9K2l6TNYcFqw8GzppCc10C+R\/q72nSInBhsDSTw3uxgP+acqC6vthAUi6ddQSsn1n8go5+hhZ\/+BG1253M3k646Lzf3auMRmIpsm7+S1ILBZ0yoDTTh4c2+MeN2WhTaoyX2aA2SN3uNtLVEKeiZS6abtkp1VnoMP0j2IXlCkP+mii\/oqche0vGbbTphq2UUANX7KnHbbO1cOZs9kQW7JKmCzXIb9qvqF3agB8R8x++FlXXvzaE0uEX2OLHI5n\/jUgTEu+jktNbX\/fXGZmPg+T0Fcy10N1LGumnMIf4DZ3LQpBMosI\/Q7O1HfZslxjibux6HTQHMQq\/3rJ4COnsYgLhHveFY05pCAKJIX+VXbW89zVgx\/7FMBse7XVNAxZM4s+cIsPT8C4k12hqFoxBlMshjSOrF2IXLo3ha7jWl9+U4pK6wlCS3jxkIRjItzHss0Wsin9GuIAwsHo9mSpjVV88g93JOWNda7m9ClSSIBf6XVmcEVnWnRASOltW+8XKt66XviOlDQ9kc+s5j9UVKrh4EJ5y1+aVitzn95F\/7YRZqwC3WKWLAnZcYkEw2Gowg9AUg5WCbpaKoWt\/BLP+Rvklq+eWl8B9IthFtiWVVNR+j8yeJur\/5jwgrEqmRysRi2gFWhrEtA+bnx9R1llfuYjHxxPjMjrtmPRwL5\/ixnEajtuXEURjd227mnRXXuj7sYPcEb2bR18PgE4YTCkSNPlKN7tEg03TLMSk5BGtNJ4vRbfuGCWDdza7AXu8jBlF7Iz4Fr1XXwRRH1Cd4p1L6ChT\/ODh1Co4nlsbj+ttjX4g8KcHBeZJnpCySC3crd5gRRSgl1Q+Ipj3Jn9RI04uSFYW+5ju9A3ssgn9Vc5IaxH++U2R4271sbTJ3hl95flFkPeqQLFBhl2BUs7MBzuaFnhzuD5aRiYln8bHzR0Xj2jGjUtTIenvf\/ooVaYMENUwkY8hu8BYJQe183rSy7Y6dSvRZLvU7pOak2u1X0j3eDXEcFqbMpoNtJUSpGy9X4SoqD4KOcbOlP6b0y63tfZ2Y+tBQx\/MF7RbuMJQN+sgD8iBltpJsYXgatTsvUw2l\/G197UjG3FrZDROIZgnFCY\/v4E4MUm8h2Vb7c7mU2WijpNMf2XL8Lk5533OltGoenaAU68qxrcSU2+xs\/tNcLql+wwxNG1p7qC1lMRKzjfI88HdFIsaOmWPG62jzmkrZqeRp0Bp6ppeJu\/IFdmus2ELqrmewgk4GSk7cm4qK\/tE9xxYg0xD50exelnOuCzJyT5EyMa89pCHKKcr1M6rn90AD6fBq7AIRvb2GP44ADTNJrDG4ZjC+e13Flp7cf5LLWByYxe\/ku4woR1g1DeJvWZnXOwuL5Z6OwmjM05MV9GvJIeIu0f469ameZlZp9n9EOE9qhqaS1hHqbLppPSnf5TEP5ElNjbv2jIWwPJbANa0CHFf1DqDM+Lh95CYgZTPozesNUasWH6\/5drnxGhiJgqVTHM0aFFO4pEVfV49hltrzoxlOy3ZfDCDw\/qYfpN9Ej9Nw8M+zjm4yWCbpjXuHa3BnZ2yBBT\/Tsb2rqrOWSffaRMVak80px9OhdW\/MSsYqIxu2F\/1l1QlzyksAQfZREfJ5mDYMGIyD2uVjK66asosDtx2qCy3vsVdatB7sT24yiZHAfh1XfWqIv6pkJNuVYCQQNMj7Yl3fhMcDKn4sKox1W\/1XPyGPYud+rZuAVzYLXgDihHRVRy3FnOgIylhSAXyQrnS3kDFIFreD3yC\/vo98BHr\/53\/UgyJtVQEtqX2MKgZYx0qrCxGTqODZ2KL6t54bN9MTZP0kLD+uwqFx1aPwudrNffCU7\/AVwte+4HjULcubQ3bsQcYYS9jDPo1upDYvvXmOlYj4dMCiO0Hvk1X1Wd6yS6Vz9SXFud3iHsfKdKcYMzSMTXX07tAnHBU0uYS5Cipbb3sKJHhmPouj+EjNpWr6D6XwPKKL4J\/N5UzMWvjFXmeu7i7AzozgrMPhRrjyAv8hIDI9+4JiJpWQKbwWek0y4uUU9TnxvRqrvv5wgX+HFMAm36UqfUzFFbfAiULEgKPIF8jDwVp3fzZyWRtZYpc8xDOLAqM2H+rQOre7\/6LNHNwHdDceY4vQ9rJ16UB+GwShFyHRmKqP2DPV7yJG11MOOAl6l1ugKGXWz22c3ulRowRP\/qBeBarbgY="
}
When encrypting with the Kotlin code, the following data is concatenated at the end:
Size of the nonce
nonce
ciphertext/tag
When decrypting with the Python code, this data must be separated.
Note that Kotlin/Java returns as ciphertext the concatenation of actual ciphertext and tag. These two parts must also be separated, since Python processes both separately.
In addition, PBKDF2 with HMAC/SHA1 is used as the key derivation in the Kotlin code. This algorithm must also be used for decryption with the Python code.
A possible implementation in Python is:
import base64
from Crypto.Hash import SHA1
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
AES_KEY_SIZE_BIT = 256
TAG_LENGTH_BIT = 128
PBKDF2_ITERATIONS = 50000
def decrypt(passphrase, salt, ciphertext):
# Separation
ciphertextBytes = base64.b64decode(ciphertext)
ivSize = int.from_bytes(ciphertextBytes[:1], "big")
iv = ciphertextBytes[1:1+ivSize]
actualCiphertext = ciphertextBytes[1+ivSize:-TAG_LENGTH_BIT//8]
tag = ciphertextBytes[-TAG_LENGTH_BIT//8:]
# Key derivation
key = PBKDF2(passphrase, salt, AES_KEY_SIZE_BIT//8, count=PBKDF2_ITERATIONS, hmac_hash_module=SHA1)
# Decryption
cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
decrypted = cipher.decrypt_and_verify(actualCiphertext, tag)
return decrypted
passphrase = "1234".encode('utf-8')
salt = bytes.fromhex("4030cc7f15e5f7bf830543270ced2b7c8b24237c53ce95382b232df69c594353")
ciphertext = "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"
print(decrypt(passphrase, salt, ciphertext).decode('utf-8')) # {"DisabledTo_basaltest":"0","DisabledTo_breadgrams":"0","DisabledTo_dia":"0","DisabledTo_exercise":"0","DisabledTo_exercise2":"0","DisabledTo_extendedcarbs":"0","DisabledTo_hypott":"0","DisabledTo_ic":"0","DisabledTo_insulin":"0","DisabledTo_iob":"0","DisabledTo_isf":"0","DisabledTo_noisycgm":"0","DisabledTo_nsclient":"0","DisabledTo_objectives":"0","DisabledTo_objectives2":"0","DisabledTo_otherMedicationWarning":"0","DisabledTo_prerequisites":"0","DisabledTo_prerequisites2":"0","DisabledTo_profileswitch":"0","DisabledTo_profileswitch2":"0","DisabledTo_profileswitch4":"0","DisabledTo_profileswitchtime":"0","DisabledTo_pumpdisconnect":"0","DisabledTo_sensitivity":"0","DisabledTo_troubleshooting":"0","DisabledTo_update":"0","DisabledTo_wrongcarbs":"0","DisabledTo_wronginsulin":"0","ExamTask_basaltest":"false","ExamTask_breadgrams":"false","ExamTask_dia":"false","ExamTask_exercise":"false","ExamTask_exercise2":"false","ExamTask_extendedcarbs":"false","ExamTask_hypott":"false","ExamTask_ic":"false","ExamTask_insulin":"false","ExamTask_iob":"false","ExamTask_isf":"false","ExamTask_noisycgm":"false","ExamTask_nsclient":"false","ExamTask_objectives":"false","ExamTask_objectives2":"false","ExamTask_otherMedicationWarning":"false","ExamTask_prerequisites":"false","ExamTask_prerequisites2":"false","ExamTask_profileswitch":"false","ExamTask_profileswitch2":"false","ExamTask_profileswitch4":"false","ExamTask_profileswitchtime":"false","ExamTask_pumpdisconnect":"false","ExamTask_sensitivity":"false","ExamTask_troubleshooting":"false","ExamTask_update":"false","ExamTask_wrongcarbs":"false","ExamTask_wronginsulin":"false","Monitor_MainActivity_resumed":"1650398254754","Monitor_MainActivity_start":"1650398048449","Monitor_MainActivity_total":"44111","Monitor_PreferencesActivity_resumed":"1650398069260","Monitor_PreferencesActivity_start":"1650398091955","Monitor_PreferencesActivity_total":"22695","Monitor_RequestDexcomPermissionActivity_resumed":"1650398253908","Monitor_RequestDexcomPermissionActivity_start":"1650398048510","Monitor_RequestDexcomPermissionActivity_total":"505","Monitor_SetupWizardActivity_resumed":"1650398049172","Monitor_SetupWizardActivity_start":"1650398061115","Monitor_SetupWizardActivity_total":"11943","Monitor_SingleFragmentActivity_resumed":"1650398286784","Monitor_SingleFragmentActivity_start":"1650398099736","Monitor_SingleFragmentActivity_total":"19515","ObjectivesActionsUsed":"true","Objectives_auto_accomplished":"0","Objectives_auto_started":"0","Objectives_autosens_accomplished":"0","Objectives_autosens_started":"0","Objectives_config_accomplished":"0","Objectives_config_started":"0","Objectives_exam_accomplished":"0","Objectives_exam_started":"0","Objectives_maxbasal_accomplished":"0","Objectives_maxbasal_started":"0","Objectives_maxiob_accomplished":"0","Objectives_maxiob_started":"0","Objectives_maxiobzero_accomplished":"0","Objectives_maxiobzero_started":"0","Objectives_openloop_accomplished":"0","Objectives_openloop_started":"0","Objectives_smb_accomplished":"0","Objectives_smb_started":"0","Objectives_usage_accomplished":"0","Objectives_usage_started":"0","absorption_cutoff":"6","activity_duration":"0","activity_target":"0","age":"adult","always_use_shortavg":"false","application_protection":"0","aps_mode":"open","autosens_max":"1.2","autosens_min":"0.7","bolus_protection":"0","boluswizard_percentage":"100","bt_watchdog":"false","carbsReqThreshold":"1","carbs_button_increment_1":"5","carbs_button_increment_2":"10","carbs_button_increment_3":"20","dexcom_lognssensorchange":"false","dexcomg5_nsupload":"false","dexcomg5_xdripupload":"false","eatingsoon_duration":"0","eatingsoon_target":"0","enableSMB_after_carbs":"false","enableSMB_always":"false","enableSMB_with_COB":"false","enableSMB_with_high_temptarget":"false","enableSMB_with_temptarget":"false","enable_carbs_required_alert_local":"true","enable_fabric2":"true","enable_missed_bg_readings":"false","enable_pump_unreachable_alert":"true","fill_button1":"0.3","fill_button2":"0","fill_button3":"0","gradually_increase_notification_volume":"false","high_mark":"0","high_temptarget_raises_sensitivity":"false","hypo_duration":"0","hypo_target":"0","insulin_button_increment_1":"0.5","insulin_button_increment_2":"1.0","insulin_button_increment_3":"2.0","keep_screen_on":"false","key_usersuperbolus":"false","language":"default","last_revoked_certs_check":"1650398043316","last_time_this_version_detected":"1650398061747","last_versionchecker_plugin_waring":"1650398048275","loop_openmode_min_change":"20","low_mark":"0","low_temptarget_lowers_sensitivity":"false","maintenance_logs_amount":"2","maintenance_logs_email":"logs#androidaps.org","master_password":"hmac:1067c3e86cb042d799eb25e9988280703563366195f38dee2d6f1f5cc05f57e6:7b29002999b3af7dd1e5fb0b2f3f4ea96ad90a410549bf0c6e34bc9ff5e5039c","missed_bg_readings_threshold":"30","nextMissedReadingsAlarm":"1650398347880","nextPumpDisconnectedAlarm":"1650398347880","ns_alarms":"false","ns_announcements":"false","openapsama_current_basal_safety_multiplier":"4","openapsama_max_daily_safety_multiplier":"3","openapsama_min_5m_carbimpact":"8.0","openapsama_useautosens":"false","openapsma_max_basal":"1","openapsmb_max_iob":"3","pump_unreachable_threshold":"30","raise_urgent_alarms_as_android_notification":"true","resistance_lowers_target":"false","sensitivity_raises_target":"true","settings_protection":"0","short_tabtitles":"false","show_calibration_button":"true","show_carbs_button":"true","show_cgm_button":"false","show_insulin_button":"true","show_notes_entry_dialogs":"false","show_statuslights":"true","show_treatment_button":"false","show_wizard_button":"true","smbinterval":"3","smbmaxminutes":"30","smscommunicator_otp_secret":"Qz12f1m7s5Tt8Q37ZB3FYFQS9ef1p3oxtYy+t9oTQ90","startupwizard_processed":"true","statuslights_bage_critical":"240","statuslights_bage_warning":"216","statuslights_bat_critical":"5","statuslights_bat_warning":"25","statuslights_cage_critical":"72","statuslights_cage_warning":"48","statuslights_iage_critical":"144","statuslights_iage_warning":"72","statuslights_res_critical":"10","statuslights_res_warning":"80","statuslights_sage_critical":"240","statuslights_sage_warning":"216","statuslights_sbat_critical":"5","statuslights_sbat_warning":"25","treatmentssafety_maxbolus":"3","treatmentssafety_maxcarbs":"48","uamsmbmaxminutes":"30","units":"mg\/dl","use_bolus_advisor":"false","use_bolus_reminder":"false","use_smb":"false","use_uam":"false","virtualpump_type":"1","virtualpump_uploadstatus":"false"}
using the posted test data.
Note that the size of the nonce should be known on both sides so that the size doesn't need to be stored.
Also, for security reasons, the (non-secret) salt should be randomly generated like the nonce and passed to the decryption side concatenated, e.g. salt|nonce|ciphertext|tag.
Have two programs, one is developed in C#.NET, having the below C# encryption/decryption functions:
public static string Encrypt(string plainText, string keyString)
{
byte[] cipherData;
Aes aes = Aes.Create();
aes.Key = Encoding.UTF8.GetBytes(keyString);
aes.GenerateIV();
aes.Mode = CipherMode.CBC;
ICryptoTransform cipher = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, cipher, CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(plainText);
}
}
cipherData = ms.ToArray();
}
byte[] combinedData = new byte[aes.IV.Length + cipherData.Length];
Array.Copy(aes.IV, 0, combinedData, 0, aes.IV.Length);
Array.Copy(cipherData, 0, combinedData, aes.IV.Length, cipherData.Length);
return Convert.ToBase64String(combinedData);
}
public static string Decrypt(string combinedString, string keyString)
{
string plainText;
byte[] combinedData = Convert.FromBase64String(combinedString);
Aes aes = Aes.Create();
aes.Key = Encoding.UTF8.GetBytes(keyString);
byte[] iv = new byte[aes.BlockSize / 8];
byte[] cipherText = new byte[combinedData.Length - iv.Length];
Array.Copy(combinedData, iv, iv.Length);
Array.Copy(combinedData, iv.Length, cipherText, 0, cipherText.Length);
aes.IV = iv;
aes.Mode = CipherMode.CBC;
ICryptoTransform decipher = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream ms = new MemoryStream(cipherText))
{
using (CryptoStream cs = new CryptoStream(ms, decipher, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
plainText = sr.ReadToEnd();
}
}
return plainText;
}
}
Another program is using Python, need to decrypt the encrypted string from the C# program.
What are the Python encryption/decryption functions so that Python's decryption function could decrypt the encrypted string by the above C# encryption function, also C#'s decryption function could decrypt the encrypted string by Python's encryption function?
The below are the Python functions worked for me:
import Crypto.Random
from Crypto.Cipher import AES
import base64
from Crypto.Util.Padding import unpad, pad
def encrypt(plain_text, key_string):
raw = pad(plain_text.encode(), AES.block_size)
iv = Crypto.Random.get_random_bytes(AES.block_size)
cipher = AES.new(key_string, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))
def decrypt(combined_string, key_string):
enc = base64.b64decode(combined_string)
iv = enc[:AES.block_size]
cipher = AES.new(key_string, AES.MODE_CBC, iv)
msg = unpad(cipher.decrypt(enc[AES.block_size:]), AES.block_size)
return msg.decode()