最近在做保密的一些東西,看了大概有不到兩天了,稍微有了一點小收獲,再次做個記錄,見證我android成長的經(jīng)歷
之前并沒有做過加密這方面的東西,前兩天有人告訴了我一個trustzone,我開始翻閱這方面的資料,開始的時候我是懵逼的,因為有一篇基礎文章寫著,trustzone基礎開發(fā)之hello_world,我還以為很簡單,就進去看了看,要求Linux環(huán)境。。。還要有一堆我沒有掌握的知識,還要用eclipse,望天。。。當時整個人是崩潰的,只能再一點點翻閱別的資料,不得不說,有的時候網(wǎng)上資料也很匱乏。。。最后我在android官方文檔上看到了這一塊的解決方案,keystory是已經(jīng)由google提供好了的api,可以實現(xiàn)trustzone的安全世界環(huán)境,將私鑰放入安全世界,永遠不會出現(xiàn)在進程世界,以此來實現(xiàn)保密,不過前些日子除了一個trustzone可以被降級攻破的新聞,算了,我一個小小的android程序員,寫著一個小小的APP,不至于會有大神來攻破我。。。。
下面放上四處搜羅來的代碼,全是血與淚,痛苦與掙扎的產(chǎn)物。。。
首先這個EC加簽驗簽(有大神看到的話能解答下我疑惑么,就是加簽和加密的區(qū)別,我就知道加簽是校驗合法性,加密是保密性,然后這個EC算法的話為什么我只能用signature來做,用Cipher就不行呢,還是說我那里沒理解,反正到現(xiàn)在也是蒙蒙的 手動攤手表示無奈:-( )
private static String src = "ecdsa security";
public static void jdkECDSA(){
try {
//1.初始化密鑰
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
keyPairGenerator.initialize(256);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
ECPublicKey ecPublicKey = (ECPublicKey)keyPair.getPublic();
String format = ecPublicKey.getFormat();
byte[] encoded = ecPublicKey.getEncoded();
ECPrivateKey ecPrivateKey = (ECPrivateKey)keyPair.getPrivate();
//2.執(zhí)行簽名
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance("SHA1withECDSA");
signature.initSign(privateKey);
signature.update(src.getBytes());
byte[] res = signature.sign();
//System.out.println("簽名:"+HexBin.encode(res));
//3.驗證簽名
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(ecPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("EC");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
signature = Signature.getInstance("SHA1withECDSA");
signature.initVerify(publicKey);
signature.update(src.getBytes());
boolean bool = signature.verify(res);
System.out.println("驗證:"+bool);
} catch (Exception e) {
e.printStackTrace();
}
}
然后是RSA的一個加密解密
public class EncryUtils {
static EncryUtils encryUtilsInstance;
KeyStore keyStore;
private PublicKey mpublicKey;
private PrivateKey mprivateKey;
public String getPublicKey() {
byte[] encoded = mpublicKey.getEncoded();
String s = new String(Base64.encode(encoded, Base64.DEFAULT));
Log.e("==============", s);
return s;
}
public static EncryUtils getInstance() {
synchronized (EncryUtils.class) {
if (null == encryUtilsInstance) {
encryUtilsInstance = new EncryUtils();
}
}
return encryUtilsInstance;
}
public EncryUtils() {
// initKeyStore();
}
private void initKeyStore(String alias){
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
}
catch(Exception e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
createNewKeys(alias);
}
}
private void createNewKeys(String alias){
if(!"".equals(alias)){
try {
// Create new key if needed
if (!keyStore.containsAlias(alias)) {
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 1);
KeyPairGeneratorSpec spec = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
spec = new KeyPairGeneratorSpec.Builder(Application.getApplication())
.setAlias(alias)
.setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
.setSerialNumber(BigInteger.ONE)
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();
}
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
generator.initialize(spec);
}
KeyPair keyPair = generator.generateKeyPair();
mpublicKey = keyPair.getPublic();
String publicKey = getPublicKey();
// mprivateKey = keyPair.getPrivate();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 加密方法
* @param needEncryptWord 需要加密的字符串
* @param alias 加密秘鑰
* @return
*/
public String encryptString(String needEncryptWord, String alias) {
if(!"".equals(alias)&&!"".equals(needEncryptWord)){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
initKeyStore(alias);
}
String encryptStr="";
byte [] vals=null;
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
// RSAPublicKey publicKey = (RSAPublicKey) privateKeyEntry.getCertificate().getPublicKey();
if(needEncryptWord.isEmpty()) {
// Toast.makeText(this, "Enter text in the 'Initial Text' widget", Toast.LENGTH_LONG).show();
return encryptStr;
}
// Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// inCipher.init(Cipher.ENCRYPT_MODE, publicKey);
inCipher.init(Cipher.ENCRYPT_MODE, privateKeyEntry.getCertificate().getPublicKey());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, inCipher);
cipherOutputStream.write(needEncryptWord.getBytes("UTF-8"));
cipherOutputStream.close();
vals = outputStream.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return Base64.encodeToString(vals, Base64.DEFAULT);
}
return "";
}
public String decryptString(String needDecryptWord, String alias) {
if(!"".equals(alias)&&!"".equals(needDecryptWord)){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
initKeyStore(alias);
}
String decryptStr="";
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
// RSAPrivateKey privateKey = (RSAPrivateKey) privateKeyEntry.getPrivateKey();
// Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// output.init(Cipher.DECRYPT_MODE, privateKey);
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(needDecryptWord, Base64.DEFAULT)), output);
ArrayList<Byte> values = new ArrayList<>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
values.add((byte)nextByte);
}
byte[] bytes = new byte[values.size()];
for(int i = 0; i < bytes.length; i++) {
bytes[i] = values.get(i).byteValue();
}
decryptStr = new String(bytes, 0, bytes.length, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return decryptStr;
}
return "";
}
}