I was directed this way from the main superuser site:
I have zero experience with Java or Android apps (I have coding experience in C) and tried reverse engineering a [now defunct/unsupported] app which would take a serial number* and encrypt it using RSA with PKCS1Padding.
I'm happy to share what I have, as the creator is uncontactable, and only a very selected few people have files (or access to the software) in relation to this, so the key can be 'in the wild'. What I believe to be the code is below... I roughly understand what it is doing.
.class public Lcom/h1dd3n/securefiles/Keygen;
.super Ljava/lang/Object;
.source "Keygen.java"
# static fields
.field static key:Ljava/lang/String;
.field static modulus:Ljava/math/BigInteger;
.field static pubExp:Ljava/math/BigInteger;
# direct methods
.method static constructor <clinit>()V
.locals 3
.prologue
const/16 v2, 0x10
.line 15
const-string v0, "00FB451D3F45D82B92FC6F243D50441DD75F2DB995842A3D389FC4536A27F42242C9C8DCB4DA0E2573E5CA2E5D0A2AD7E790D8A79CAC2DE68BEAF99D21E229A9CF04ABD09D61C8C66C4FE3B32456496305792FF9D2D2198B87BFAB2637518C1D3F44D27B93EF2C0ED3379993D04944EB356D4BDE343017CFB13405B403A3D81D2C7B099AE5651CF14DD3CBE21C435076F244D9DA8F54DA19BA6301AF1F7DA699E2EBFD9C0BB2778D812E8D9BE66089B2783B9E60FA28FA83CD3B356669BC15BC84058FEEE493CCFBE2E13E0B53B01886D47EB75BFC75758A5CFA5A1836E697FD51846578B4BDEDE3A6BD1FE4D49ABAC072AED433AC5A19BF94C9F6C7F4D95740EF"
sput-object v0, Lcom/h1dd3n/securefiles/Keygen;->key:Ljava/lang/String;
.line 16
new-instance v0, Ljava/math/BigInteger;
sget-object v1, Lcom/h1dd3n/securefiles/Keygen;->key:Ljava/lang/String;
invoke-direct {v0, v1, v2}, Ljava/math/BigInteger;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/h1dd3n/securefiles/Keygen;->modulus:Ljava/math/BigInteger;
.line 17
new-instance v0, Ljava/math/BigInteger;
const-string v1, "010001"
invoke-direct {v0, v1, v2}, Ljava/math/BigInteger;-><init>(Ljava/lang/String;I)V
sput-object v0, Lcom/h1dd3n/securefiles/Keygen;->pubExp:Ljava/math/BigInteger;
return-void
.end method
.method public constructor <init>()V
.locals 0
.prologue
.line 14
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static encrypt(Ljava/lang/String;)[B
.locals 7
.param p0, "text" # Ljava/lang/String;
.prologue
.line 23
:try_start_0
new-instance v2, Ljava/security/spec/RSAPublicKeySpec;
sget-object v5, Lcom/h1dd3n/securefiles/Keygen;->modulus:Ljava/math/BigInteger;
sget-object v6, Lcom/h1dd3n/securefiles/Keygen;->pubExp:Ljava/math/BigInteger;
invoke-direct {v2, v5, v6}, Ljava/security/spec/RSAPublicKeySpec;-><init>(Ljava/math/BigInteger;Ljava/math/BigInteger;)V
.line 24
.local v2, "keySpec":Ljava/security/spec/RSAPublicKeySpec;
const-string v5, "RSA"
invoke-static {v5}, Ljava/security/KeyFactory;->getInstance(Ljava/lang/String;)Ljava/security/KeyFactory;
move-result-object v3
.line 25
.local v3, "kf":Ljava/security/KeyFactory;
invoke-virtual {v3, v2}, Ljava/security/KeyFactory;->generatePublic(Ljava/security/spec/KeySpec;)Ljava/security/PublicKey;
move-result-object v4
.line 27
.local v4, "publicKey":Ljava/security/PublicKey;
const-string v5, "RSA/ECB/PKCS1Padding"
invoke-static {v5}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;
move-result-object v0
.line 28
.local v0, "cipher":Ljavax/crypto/Cipher;
const/4 v5, 0x1
invoke-virtual {v0, v5, v4}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;)V
.line 29
invoke-virtual {p0}, Ljava/lang/String;->getBytes()[B
move-result-object v5
invoke-virtual {v0, v5}, Ljavax/crypto/Cipher;->doFinal([B)[B
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
move-result-object v5
.line 35
.end local v0 # "cipher":Ljavax/crypto/Cipher;
.end local v2 # "keySpec":Ljava/security/spec/RSAPublicKeySpec;
.end local v3 # "kf":Ljava/security/KeyFactory;
.end local v4 # "publicKey":Ljava/security/PublicKey;
:goto_0
return-object v5
.line 31
:catch_0
move-exception v1
.line 33
.local v1, "e":Ljava/lang/Exception;
invoke-virtual {v1}, Ljava/lang/Exception;->printStackTrace()V
.line 35
const/4 v5, 0x0
goto :goto_0
.end method
Now I have a file of which I wish to view the original contents that was encrypted using this method. How on earth do I do that? I'd also be interested in creating new files in a similar way on a Windows based system if possible...
Full APK source (minus resources as some confidential stuff in there) is available here (it only worked on some v5/v6 Android devices)
File I wish to decrypt is [here]
the file is generated in SecureKeySource\smali\com\tmsec\securedisk\Activator and saved onto the SD Card.
Serial number is the manufacturer's data from an SD card which is then encrypted and used by another piece of software to allow access. The device was password write protected to prevent deletion/formatting. If you lost this SD card you were screwed as you couldn't access the programs! The device would be checked and deny access if there was a data mismatch. This was the most secure method on an extremely low budget that was thought of at the time of creation - a few years back now; why they did it this way I do not know... I have key backups but no way of associating them with cards or no methods of creating new cards without buying old android tablets/phones and hoping they work with microSD cards (no idea how they originally did it on normal SD cards!! OTG adapters don't seem to show the manufacturer data?). I do have the password to remove write access allowing the cards to be formatted however as that was recorded at least.
I was hoping that (looking at the extracted source code) there would be some sort of KeyGenerator class where I could enter the new ID as a string and then run.