September 17, 2018

Простейшая проверка подписи на Java

Мой канал: @VolfsChannel

Данная проверка является т.н. "классикой жанра" и первым (иногда и последним) рубежом защиты. Данный пример до безобразия прост, но тем и привлекателен. Никаких заумных и запутанных действий, только рабочий код.

Весь код проверки умещается в одном методе. Имена переменных изменены специально.

Реализация

Объявляем поля:

private static PackageManager pm;
private static String name;
private static String s;
private static byte[] bs;
private static Signature[] sa;

Проверяем подпись:

@SuppressLint("PackageManagerGetSignatures")
		public boolean b(String st) {
				try {
						pm = getApplicationContext().getPackageManager();
						name = getApplicationContext().getPackageName();
						sa = pm.getPackageInfo(name, PackageManager.GET_SIGNATURES).signatures;
						//Log.w(Constants.TAG, "Signature[] :: " + Arrays.toString(sa));
						for (Signature a$a : sa) {
								//Log.w(Constants.TAG, "byte[] :: " + Arrays.toString(bs));
								bs = a$a.toByteArray();
								//Log.w(Constants.TAG, "new byte[] :: " + Arrays.toString(bs));
								bs = CertificateFactory.getInstance("X509").generateCertificate(
									new ByteArrayInputStream(bs)).getEncoded();
								//Log.w(Constants.TAG, "new byte[] encoded :: " + Arrays.toString(bs));
								s = new String(Base64.encode(MessageDigest.getInstance("MD5").digest(bs), 19));
								//Log.w(Constants.TAG, "result string :: " + s);
								return Objects.equals(s, st);
							}
					} catch (Exception e) {
						return false;
					}
				return false;
			}

Теперь пройдемся по коду, хотя, те кому надо и так уже поняли...

На вход поступает String st.

Следующие 3 строчки - инициализация объектa PackageManager, у которого мы узнаем наше имя пакета. С помощью этого имени мы получаем массив сигнатур - ту самую подпись.

Преобразуем нашу подпись в массив байт. Из полученного массива мы создаём сертификат X509. Шифруем MD5 нашего сертификата с помощью Base64, и сравниваем получившийся String с переменной st.

Что такое st? Как его получить? Создать новый метод с возвращением String, и вернуть s

А наглядно можно?

Конечно. Чтобы продемонстрировать работу кода, я создал простое приложение. Чтобы узнать хэш вашей подписи, просто переподпишите его вашей подписью.

Подписи совпадают:

Подписи не совпадают:

Скачать данное приложение и его исходный код можно на канале.

@VolfsChannel