Освой программирование играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Я не разбираюсь в криптографии и статья выложена только для ознакомления.
Android имеет в своём составе пакет javax.crypto с классами, которые отвечают за шифрование, дешифрование, ключи и т.п. Если вы занимались этой темой в Java, то многое будет знакомо. Поддерживаются популярные алгоритмы AES и RSA.
Для начала получим список провайдеров и поддерживаемые ими сервисы и алгоритмы.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Список провайдеров" />
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
</ScrollView>
</LinearLayout>
Код по щелчку кнопки
public void onClick(View view) {
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(getSecurityProviders());
}
public String getSecurityProviders() {
String result = "";
Provider[] providers = Security.getProviders();
for (int i = 0; i < providers.length; i++) {
// Получим все сервисы для выбранного провайдера
Set<Object> ks = providers[i].keySet();
Set<String> servicetypes = new TreeSet<>();
for (Iterator<Object> it = ks.iterator(); it.hasNext(); ) {
String k = it.next().toString();
k = k.split(" ")[0];
if (k.startsWith("Alg.Alias."))
k = k.substring(10);
servicetypes.add(k.substring(0, k.indexOf('.')));
}
// Получим все алгоритмы для выбранного типа сервиса
int s = 1;
for (Iterator<String> its = servicetypes.iterator(); its.hasNext(); ) {
String stype = its.next();
Set<String> algorithms = new TreeSet<>();
for (Iterator<Object> it = ks.iterator(); it.hasNext(); ) {
String k = it.next().toString();
k = k.split(" ")[0];
if (k.startsWith(stype + "."))
algorithms.add(k.substring(stype.length() + 1));
else if (k.startsWith("Alg.Alias." + stype + "."))
algorithms.add(k.substring(stype.length() + 11));
}
int a = 1;
for (Iterator<String> ita = algorithms.iterator(); ita.hasNext(); ) {
result += ("[П#" + (i + 1) + ":" + providers[i].getName() + "]" +
"[С#" + s + ":" + stype + "]" +
"[А#" + a + ":" + ita.next() + "]\n");
a++;
}
s++;
}
}
return result;
}
Популярный алгоритм симметричного шифрования Advanced Encryption Standard (AES).
Зададим тестовую строку, зашифруем и расшифруем её.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textViewOriginal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/textViewEncoded"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/textViewDecoded"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
</LinearLayout>
Весь процесс происходит в методе onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Original text
String testText = "А у нас сегодня кошка родила вчера котят";
TextView originalTextView = (TextView) findViewById(R.id.textViewOriginal);
originalTextView.setText("[ORIGINAL]:\n" + testText + "\n");
// Set up secret key spec for 128-bit AES encryption and decryption
SecretKeySpec sks = null;
try {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed("any data used as random seed".getBytes());
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128, sr);
sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");
} catch (Exception e) {
Log.e("Crypto", "AES secret key spec error");
}
// Encode the original data with AES
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, sks);
encodedBytes = c.doFinal(testText.getBytes());
} catch (Exception e) {
Log.e("Crypto", "AES encryption error");
}
TextView encodedTextView = (TextView)findViewById(R.id.textViewEncoded);
encodedTextView.setText("[ENCODED]:\n" +
Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");
// Decode the encoded data with AES
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, sks);
decodedBytes = c.doFinal(encodedBytes);
} catch (Exception e) {
Log.e("Crypto", "AES decryption error");
}
TextView decodedTextView = (TextView)findViewById(R.id.textViewDecoded);
decodedTextView.setText("[DECODED]:\n" + new String(decodedBytes) + "\n");
}
Разметку оставляем без изменений. Используем другой алгоритм RSA:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Original text
String testText = "А у нас сегодня кошка родила вчера котят";
TextView originalTextView = (TextView) findViewById(R.id.textViewOriginal);
originalTextView.setText("[ORIGINAL]:\n" + testText + "\n");
// Generate key pair for 1024-bit RSA encryption and decryption
Key publicKey = null;
Key privateKey = null;
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
publicKey = kp.getPublic();
privateKey = kp.getPrivate();
} catch (Exception e) {
Log.e("Crypto", "RSA key pair error");
}
// Encode the original data with RSA private key
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.ENCRYPT_MODE, privateKey);
encodedBytes = c.doFinal(testText.getBytes());
} catch (Exception e) {
Log.e("Crypto", "RSA encryption error");
}
TextView encodedTextView = (TextView)findViewById(R.id.textViewEncoded);
encodedTextView.setText("[ENCODED]:\n" +
Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");
// Decode the encoded data with RSA public key
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.DECRYPT_MODE, publicKey);
decodedBytes = c.doFinal(encodedBytes);
} catch (Exception e) {
Log.e("Crypto", "RSA decryption error");
}
TextView decodedTextView = (TextView)findViewById(R.id.textViewDecoded);
decodedTextView.setText("[DECODED]:\n" + new String(decodedBytes) + "\n");
}
По мотивам статьи Android Encryption with the Android Cryptography API