Android中的RSA,解密未知密钥类型错误

时间:2016-12-19 10:40:35

标签: java android encryption cryptography rsa

我在android中尝试了RSA加密,我在这里创建了一个RSA类,用于在共享首选项中生成和存储密钥对。我成功地存储和访问了公钥。但是在访问私钥时,它会抛出InvalidKeyException: unknown key type passed to RSA

以下是班级和活动的代码:

主要活动

public class MainActivity extends AppCompatActivity {

static final String TAG = "AsymmetricALgorithmRSA";
private TextView txt1, txt2, txt3;
private Button btn=null;
private RSAcipher cipher=null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    txt1 = (TextView) findViewById(R.id.tx1);
    txt2 = (TextView) findViewById(R.id.tx2);
    txt3 = (TextView) findViewById(R.id.tx3);
    btn = (Button) findViewById(R.id.button);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent nw = new Intent(getApplicationContext(), MainActivity.class);
            startActivity(nw);
        }
    });


    // Setting up the RSA Ciphering Class
    cipher = RSAcipher.getInstance(getApplicationContext());

    // Setting the original text:
    String ogTxt = "This is the original text";
    txt1.setText("\n[ORIGINAL TEXT]\n"+ogTxt+"\n");

    // Getting encoded text
    String enstr = cipher.getEncoded(ogTxt);

    //  Displaying Encoded Text
    txt2.setText("\n[ENCODED TEXT]\n"+ enstr +"\n");

    // Displaying Decoded Text
    txt3.setText("\n[DECODED TEXT]\n"+ cipher.getDecoded(enstr) +"\n");
}

@Override
public void onPause(){
    super.onPause();
    finish();
}}

RSA班级

public class RSAcipher {

private static final String TAG = "RSA Cipher";

private SharedPreferences keyDat=null;
private SharedPreferences.Editor keyEdit=null;
private String
        pubKeyStr=null,
        priKeyStr=null;
private Key
        publicKey=null,
        privateKey=null;

private static Context ct=null;
private static RSAcipher savedInstance=null;

public static RSAcipher getInstance(Context context) {
    ct = context;
    if(savedInstance==null){
        savedInstance = new RSAcipher();
    }
    return savedInstance;
}

private RSAcipher() {
    keyDat = PreferenceManager.getDefaultSharedPreferences(ct);
    keyEdit = keyDat.edit();
    pubKeyStr = keyDat.getString("spPubKeyTag",null);
    priKeyStr = keyDat.getString("spPriKeyTag",null);
    if(pubKeyStr==null && priKeyStr==null){
        generateKeys();
    }
}

private void generateKeys(){
    try{
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
        kpg.initialize(1024, new SecureRandom());
        KeyPair keyPair = kpg.genKeyPair();
        publicKey = keyPair.getPublic();
        privateKey = keyPair.getPrivate();

        byte[] pubByte = publicKey.getEncoded();
        pubKeyStr = new String(Base64.encodeToString(pubByte,Base64.DEFAULT));
        byte[] priByte = privateKey.getEncoded();
        priKeyStr = new String(Base64.encodeToString(priByte,Base64.DEFAULT));

        keyEdit.putString("spPubKeyTag",pubKeyStr);
        keyEdit.putString("spPriKeyTag",priKeyStr);
        keyEdit.commit();
    } catch (Exception e){
        Log.e(TAG,"key generation error");
    }
}

private Key getPubKey(){
    String pubKeyStr = keyDat.getString("spPubKeyTag", "");
    byte[] sigBytes = Base64.decode(pubKeyStr, Base64.DEFAULT);
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes);
    KeyFactory keyFact = null;
    try {
        keyFact = KeyFactory.getInstance("RSA", "BC");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    }
    try {
        return  keyFact.generatePublic(x509KeySpec);
    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    }
    return null;
}

private  Key getPriKey(){
    String privKeyStr = keyDat.getString("spPriKeyTag", "");
    byte[] sigBytes = Base64.decode(privKeyStr, Base64.DEFAULT);
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes);
    KeyFactory keyFact = null;
    try {
        keyFact = KeyFactory.getInstance("RSA", "BC");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    }
    try {
        return  keyFact.generatePrivate(x509KeySpec);
    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    }
    return null;
}

public String getEncoded(String str){
    if(publicKey==null){
        publicKey = getPubKey();
    }
    String enstr = new String();
    byte[] encodedBytes = null;
    try{
        Cipher c = Cipher.getInstance("RSA", "BC");
        c.init(Cipher.ENCRYPT_MODE,publicKey);
        encodedBytes = c.doFinal(str.getBytes());
    } catch (Exception e){
        Log.e(TAG, "RSA Encryption error");
    }
    enstr = Base64.encodeToString(encodedBytes,Base64.DEFAULT);
    return enstr;
}

public  String getDecoded(String str){
    if(privateKey==null){
        privateKey = getPriKey();
    }
    String destr = new String();
    byte[] encodedBytes = Base64.decode(str,Base64.DEFAULT);
    byte[] decodedBytes = null;
    try{
        Cipher c = Cipher.getInstance("RSA", "BC");
        c.init(Cipher.DECRYPT_MODE,privateKey);
        decodedBytes = c.doFinal(encodedBytes);
    }catch(Exception e){
        Toast.makeText(ct, e.toString(), Toast.LENGTH_LONG).show();
    }
    try{destr = new String(decodedBytes);}catch (Exception e){}
    return destr;
}}

问题仅在解密文本时发生。它加密没有任何麻烦。请简化您的解决方案的解释,因为我对此很陌生。谢谢。

1 个答案:

答案 0 :(得分:1)

X509EncodedKeySpec用于公钥。替换

X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes);

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(sigBytes);

它应该工作。如果没有尝试将private显式编码为pkcs8

KeyFactory fact = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec spec = fact.getKeySpec(privateKey, PKCS8EncodedKeySpec.class);
byte[] privateKeyBytes = spec.getEncoded();