Eğer size veri gönderen kaynağın doğruluğunu garanti altına almanız gerekiyorsa bu durumda şifrelemeden farklı bir yol izlemeniz gerekir. Bu işlem için veri imzalama (data signing) tekniği kullanılır.

Şifreleme yaparken gönderilen veri açık anahtar (public key) kullanıldığından ve şifrelenmiş veriyi çözmek için sır anahtar (private key) kullanıldığından bahsetmiştik. İmzalamada durum tam tersidir. İmza (signature) üretmek için private key kullanılır ve doğrulamak (verifing) için public key kullanılır.

Public cryptography algoritmaları bu işlem için kullanılabilir. Ben bu yazımda daha önce tercih ettiğim gibi RSA algoritmasını tercih edeceğim.

Örneklerimizde kullanacağımız anahtarları üretmek için Java ile RSA anahtar üretme yazımı inceleyebilirsiniz.

Veri imzalama (signing) işlemi private key ile aşağıdaki gibi gerçekleştirilir.

// Anahtarımızı byte dizisine çevirelim.
byte[] modulusBytes = Base64.decode("AJmvQm09j0UQEvHgZVt6KFjF8SI6Tj1M4xCpU1/Tof14UrUQycR238bFbbIVYuoyXGCsKi/kEqCJyZ0GrDeShXLaVoD5ErPZ7Yw6KMXsoprYlRo77h7zqb6Bep+UUhRtPR/PIhUoaLzDX3UaqKuEiaLlQcILqhqePIFtfrRZafT/zLIDGtyMOGK9E0API7ADddLPBd3jVqDUBA4mSXFqBOVIi+nHxvvEDi5IEdisEVYvKYv7xeAklsPRKmeQ0PsbO16z2fq4iXhus6Wn9Kcf/I4sz/AsF0puTlDczVScPdzRtVRM9lPg68MWFM10WaFmmJ4alNGmn0pDlWD9jsXLk2k=", Base64.DEFAULT);
byte[] exponentBytes = Base64.decode("AmWHRajWGR+dDASR0BFhm7DKh9wc6DvQtqvNTws/1XIQ6B3w541rA/CEO2i1+Cz8380Pg1utJq+/YyF9gghY6GebPbuknQVi/PLTO/LqvjtuZ9BTcEwgc4YVYXOwq/zgHSTfxTCyIW9yh6L4ymPwuYeVtO71oiChlOseNLXIPzfPyw51pbn4TBlAEkDY+ppNy2F+x6YBEe37V315BrZ3u6Xq0co/Ut9ldZyuIPnsGk80WbCrDqtz2Klx1NgRcLCe+sRYR/5naRNNI+Ut+ilDR4RlGYlGkPluP/o6QSD2EtatJCmpddXt9I2tmneEauRo+AF/SYHjoPUJQm1IKFz24Q==", Base64.DEFAULT);

// Algoritme BigInteger objesi istiyor. Aynı bizim bu anahtarları ilk ürettiğimzde bize verdiği gibi.
BigInteger modulusBigInteger = new BigInteger(1, modulusBytes);
BigInteger exponentBigInteger = new BigInteger(1, exponentBytes);

// Anahtarımızla şifreleme için kullanacağımız PublicKey objemizi hazırlayalım.
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(modulusBigInteger, exponentBigInteger);
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

// İmzalanacak verimiz.
String data = "Signing and Verifing data with RSA";
// Verimizi byte dizisine çevirelim.
byte[] dateBytes = data.getBytes("UTF-8");

// İmzalama objemizi hazırlayalım.
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(privateKey);
signature.update(dateBytes);

// İmzalama işlemini aşağıdaki gibi uygulayalım.
byte[] signatureBytes = signature.sign();
// Veri ile beraber güvenle taşımak için Base64'e çevirelim.
String signatureBase64 = Base64.encodeToString(signatureBytes, Base64.DEFAULT);

İmza doğrulama (verifing) benzer şekilde public key kullanılarak aşağıdaki gibi uygulanır.

// Anahtarımızı byte dizisine çevirelim.
byte[] modulusBytes = Base64.decode("AJmvQm09j0UQEvHgZVt6KFjF8SI6Tj1M4xCpU1/Tof14UrUQycR238bFbbIVYuoyXGCsKi/kEqCJyZ0GrDeShXLaVoD5ErPZ7Yw6KMXsoprYlRo77h7zqb6Bep+UUhRtPR/PIhUoaLzDX3UaqKuEiaLlQcILqhqePIFtfrRZafT/zLIDGtyMOGK9E0API7ADddLPBd3jVqDUBA4mSXFqBOVIi+nHxvvEDi5IEdisEVYvKYv7xeAklsPRKmeQ0PsbO16z2fq4iXhus6Wn9Kcf/I4sz/AsF0puTlDczVScPdzRtVRM9lPg68MWFM10WaFmmJ4alNGmn0pDlWD9jsXLk2k=", Base64.DEFAULT);
byte[] exponentBytes = Base64.decode("AQAB", Base64.DEFAULT);

// Algoritme BigInteger objesi istiyor. Aynı bizim bu anahtarları ilk ürettiğimzde bize verdiği gibi.
BigInteger modulusBigInteger = new BigInteger(1, modulusBytes);
BigInteger exponentBigInteger = new BigInteger(1, exponentBytes);

// Anahtarımızla şifreleme için kullanacağımız PublicKey objemizi hazırlayalım.
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulusBigInteger, exponentBigInteger);
PublicKey publicKey = keyFactory.generatePublic(keySpec);

// İmzalanmış verimiz.
String data = "Signing and Verifing data with RSA";
// Verimizi byte dizisine çevirelim.
byte[] dateBytes = data.getBytes("UTF-8");
// Verimizin imzasını Base64'den byte dizisine çeviriyoruz.
byte[] signatureBytes = Base64.decode("f9m3oQfKDuXcUbM2orogFb+VfAp3HL0CiEvprThC2pwapKcbA0p7YDVbEHA+9aQQNCIIZrNpJ893M/XDjWWO8qBmG6ktv6LnIF9dOkpdT9Xb/ghD8mCUvE46taLLeoTkpj/Uosb9FY+d6t6j9gnJWEybErjxgduvR4/zL0LPlO5pO4ji8yxfW6uutAIB75JHeG0RwJPdb9S+Hc2FYFq/NR9ICZLHOoeb02JiZcxQi7qFN7vcWIyEvm2/qQ9GtcNniZwd2Pw3uHnwqysqdcxbwjx6L8CypgRO3ow+HDcv4AJGIxbqzimILCKEZ7f7SDr4vHjaVYHChWoLeUD0GEpoMA==", Base64.DEFAULT);

// Doğrulama objelerimizi hazırlayalım.
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(publicKey);
signature.update(dateBytes);

// Doğrulama aşağıdaki şekilde gerçekleşti
boolean verified = signature.verify(signatureBytes);

Image

Bu yazımda Android platformunda RSA algoritmasını kullanarak veri imzalama ve imza doğrulama konusuna değindik. Başka bir yazıda görüşmek üzere..