اجزاء معماری سیستم عامل اندروید (قسمت اول رمزنگاری اندروید) :: بخش پنجم
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: سه دقیقه

پیاده سازی رمزنگاری کجا و به چه صورتی انجام می‌شود؟

ما داده‌ها را قبل از اینکه آن‌ها را به کارت SD ارسال کنیم، نگهداری و رمز می‌کنیم. به این ترتیب داده‌های ما در کارت SD در فرمتی که می‌تواند توسط هر کسی خوانده شود نوشته شده و هرگز اجازه دسترسی به آنها مقدور نمی‌باشد. یک مهاجم که اطلاعات رمزنگاری شده شما را جمع‌آوری می‌کند باید ابتدا از رمز عبور برای رمزگشایی داده‌ها قبل از دسترسی به آن‌ها استفاده کند که در این مرحله دچار سردرگمی خواهد شد؛ چرا که فرمت هر نوع از داده‌ها یکسان نخواهند بود! ما از الگوریتم AES برای رمزکردن داده‌ها با استفاده از یک گذرواژه یا کلید استفاده خواهیم کرد. در این صورت یک کلید برای رمزگذاری و رمزگشایی داده‌ها مورد نیاز است. این رمزگذاری کلید متقارن ( Symmetric-key ) نیز نامیده می‌شود. 
برخلاف رمزنگاری کلید عمومی، این کلید تنها کلید استفاده‌شده برای رمزگذاری و رمزگشایی داده‌ها است. این کلید باید به طور ایمن ذخیره شود؛ چون اگر از دست رفته یا فاش شده باشد، یک مهاجم می‌تواند از آن برای رمزگشایی استفاده کند. کدهای زیر روشی از رمزگذاری را نشان می‌دهد:
privatestaticbyte[] encrypt(byte[] key, byte[] data) {
 SecretKeySpec sKeySpec = new SecretKeySpec(key, "AES");
 Cipher cipher;
 byte[] ciphertext = null;
 try {
  cipher = Cipher.getInstance("AES");
  cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
  ciphertext = cipher.doFinal(data);
 } catch (NoSuchAlgorithmException e) {
  Log.e(TAG, "NoSuchAlgorithmException");
 } catch (NoSuchPaddingException e) {
  Log.e(TAG, "NoSuchPaddingException");
 } catch (IllegalBlockSizeException e) {
  Log.e(TAG, "IllegalBlockSizeException");
 } catch (BadPaddingException e) {
  Log.e(TAG, "BadPaddingException");
 } catch (InvalidKeyException e) {
  Log.e(TAG, "InvalidKeyException");
 }
 return ciphertext;
}
اجازه دهید این قسمت را بخش به بخش توضیح دهم. اولین سطر کد از کلاس SecretKeySpec استفاده کرده و یک نمونه جدید از کلاس Cipher را برای تهیه یک کلید مخفی AES به وجود می‌آورد. 
SecretKeySpec sKeySpec = new SecretKeySpec(key,"AES");
Cipher cipher;
byte[] ciphertext = null;
همچنین کد بالا یک آرایه از بایت‌ها را برای ذخیره متن رمزی در ciphertext ایجاد می‌کند. بخش بعدی این کد برای استفاده از الگوریتم AES استفاده شده است که مشاهده می‌کنید.
cipher = Cipher.getI nstance ( " AES " ) ;
cipher.init ( Cipher.ENCR ypt _ MODE , sKeySpec ) ;
 تابع cipher.init شئ ای از تابع Cipher است؛ بنابراین می‌تواند با استفاده از کلید رمز تولید شده، رمزنگاری را انجام دهد. خط بعدی کد، داده‌های متنی را تغییر می‌دهد و محتویات رمز شده را در آرایه‌ای از بایت کدها ذخیره می‌کند که در کد زیر مشاهده می‌شود:
ciphertext = cipher.doFinal(data);
مهم است که ما از همان کلید برای جریان رمزگشایی نیز استفاده کنیم. در غیر این صورت، شکست خواهیم خورد و کلید، عمومی می‌شود. به طور کلی بهتر است که والد کلید اصلی را بنویسید و یک عدد تصادفی را تولید کند. این کار باعث می‌شود که فرد مهاجم به چیزی بیش از یک گذرواژه عادی فکر کند! برای نمونه کدهای زیر، کلید تولید شده با استفاده از الگوریتم را نشان می‌دهند:
publicstaticbyte[] generateKey(byte[] randomNumberSeed) {
 SecretKey sKey = null;
 try {
  KeyGenerator keyGen = KeyGenerator.getInstance("AES");
  SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
  random.setSeed(randomNumberSeed);
  keyGen.init(256, random);
  sKey = keyGen.generateKey();
 } catch (NoSuchAlgorithmException e) {
  Log.e(TAG, "No such algorithm exception");
 }
 return sKey.getEncoded();
}
در کد بالا، اعداد تصادفی با استفاده از SHA1 کدگذاری می‌شوند. الگوریتم SHA1 یا دیگر الگوریتم‌های هش، توابع رمزنگاری را مدیریت می‌کنند. این الگوریتم بر روی یک قطعه از داده‌ها عمل می‌کند که دارای یک طول غیریکسان هستند و یک رشته کوتاه با اندازه ثابت را تولید می‌کند. اگر هر قطعه‌ای از داده‌ها تغییر کند، آنگاه نتایج نهایی در آن مجموعه دچار تغییر خواهند شد و رمزنگاری، نتایج دیگری خواهد داشت! این نشانه‌ای است از اینکه یک قطعه از داده‌ها دستکاری شده‌است!