探索黑客技术攻防,实战研究与安全创新

导航菜单

Android实现文件非对称加密存储

在上一篇文章实现了android通过证书文件进行安全传输的基础上,这篇文章讲解实现在android中通过非对称加密算法进行文件保存。

如何生成证书请参见“自定义证书android实现HTTPS通信”文章所述。在android中,通过KeyStore加载证书文件,并获取相应的PublicKey,通过Cipher设置对应的数据填充方式,此处要注意,填充的方式要与解密的方式相对应,否则会爆出异常。

主要实现代码如下:


@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButtonbtnSearch=(Button)findViewById(R.id.button1);
btnSearch.setOnClickListener(this);
}
@Override
publicbooleanonCreateOptionsMenu(Menumenu){
getMenuInflater().inflate(R.menu.main,menu);
returntrue;
}
@Override
publicvoidonClick(Viewv){
//TODOAuto-generatedmethodstub
try{
PublicKeypublicKey=loadRSAPublicKey();
StringstrText=这里是机密信息!!!;
byte[]bsText=strText.getBytes(UTF-8);
byte[]bsEncode=encryptData(bsText,publicKey);
saveFile(bsEncode);
}catch(NoSuchAlgorithmExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(CertificateExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(NotFoundExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(KeyStoreExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
privatevoidsaveFile(byte[]bsData)throwsIOException{
Filefile=newFile(Environment.getExternalStorageDirectory(),encryptData.dat);
FileOutputStreamfileOutputStream=newFileOutputStream(file);
fileOutputStream.write(bsData);
fileOutputStream.close();
}
private
PublicKey
loadRSAPublicKey()
throws
NoSuchAlgorithmException,
CertificateException,NotFoundException,IOException,KeyStoreException{
KeyStorets=null;
ts=KeyStore.getInstance(BKS);
ts.load(getResources().openRawResource(R.raw.mycert),123456.toCharArray());
EnumerationStringenumAliases=ts.aliases();
StringstrAliases=enumAliases.nextElement();
PublicKeypublicKey=ts.getCertificate(strAliases).getPublicKey();
returnpublicKey;
}
/*
*数据加密
*/
publicstaticbyte[]encryptData(byte[]data,PublicKeypublicKey)
{
try
{
Ciphercipher=Cipher.getInstance(RSA/ECB/PKCS1Padding);
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
returncipher.doFinal(data);
}catch(Exceptione)
{
e.printStackTrace();
returnnull;
}
}
生成完成加密文件后,我们通过adb将加密的文件导入到电脑中。
adb
pull
/sdcard/encryptData.dat
c:\encryptData.dat


在pc端,通过一个c#程序进行解密,并显示出被加密的数据,通过X509Certificate2加载pfx证书文件,并获得私钥对象RSACryptoServiceProvider,将私钥对象赋予RSACryptoServiceProvider对象后通过调用Decrypt获得解密后的byte数组。最后需要对byte数组进行utf-8编码成字符串后进行显示。主要代码如下:


static
{
voidMain(string[]args)
stringstrCertFileFullName=@D:\cert\myCert.pfx;
stringstrFileName=@c:\encryptData.dat;
FileStreamfs=newFileStream(strFileName,FileMode.Open,FileAccess.Read);
byte[]encryptedData=newbyte[fs.Length];
fs.Read(encryptedData,0,encryptedData.Length);
fs.Close();
X509Certificate2
prvcrt
=
new
X509Certificate2(strCertFileFullName,
,
X509KeyStorageFlags.Exportable);
RSACryptoServiceProviderprvkey=(RSACryptoServiceProvider)prvcrt.PrivateKey;
byte[]decryptedData=RSADecrypt(encryptedData,prvkey.ExportParameters(true),
false);
prvkey.Clear();
Console.WriteLine(解密出的信息:\n{0},Encoding.UTF8.GetString(decryptedData));
}
staticpublicbyte[]RSADecrypt(byte[]DataToDecrypt,RSAParametersRSAKeyInfo,bool
DoOAEPPadding)
{
try
{
byte[]decryptedData;
using(RSACryptoServiceProviderRSA=newRSACryptoServiceProvider())
{
RSA.ImportParameters(RSAKeyInfo);
decryptedData=RSA.Decrypt(DataToDecrypt,false);
}
returndecryptedData;
}
catch(CryptographicExceptione)
{
Console.WriteLine(e.ToString());
returnnull;
}
}


执行结果如图1所示。

A44.png

图1

(完)