我在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;
}}
问题仅在解密文本时发生。它加密没有任何麻烦。请简化您的解决方案的解释,因为我对此很陌生。谢谢。
答案 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();