プライバシーデータの送信方法
ユーザーのプライバシー情報を送信する際は、必ずPOSTメソッドを使用してください。GETリクエストではすべてのパラメータがURLに直接表示され、リクエストURLはサーバーのアクセスログに記録されることが多いため、攻撃者の標的となりやすいのです。
プライバシー情報には以下のようなものがあります:
- ログインパスワード
- 銀行口座情報
- その他個人情報
データセキュリティの重要性
単にPOSTリクエストを使用するだけでは、セキュリティ問題は完全には解決しません。ソフトウェア(例:Charles)を使用してプロキシサーバーを設定し、スマートフォンの通信データを傍受・確認することが可能です。そのため、プライバシー情報を送信する際は、必ず暗号化処理を施してから送信する必要があります。
一般的な暗号化アルゴリズム
以下に代表的な暗号化アルゴリズムを挙げます:
MD5 \ SHA \ DES \ 3DES \ RC2とRC4 \ RSA \ IDEA \ DSA \ AES
暗号化アルゴリズムの選択:
一般的に、各企業には独自の暗号化規格があり、そのインターフェース仕様書に従って暗号化処理を実装する必要があります。
MD5暗号化の詳細
MD5とは
正式名称は「Message Digest Algorithm 5」で、「メッセージダイジェストアルゴリズム第5版」と訳されます。入力情報に対して128ビットのハッシュ値(32文字)を生成する効果があります。
MD5の特徴
- 異なる2つの入力から同じ出力が得られることはありません
- 出力値から元の平文を復元することは不可能(不可逆性)
MD5の応用例
MD5は比較的高い安全性を持ち、無料で利用可能なため、広く使用されています。主にデジタル署名、ファイル完全性検証、パスワード暗号化などに活用されます。
MD5復元サイト:http://www.cmd5.com
MD5の改良方法
現在のMD5は絶対安全とは言えません。そのため、以下のような改良を加えることで、復元の難易度を高めることができます:
- ソルト(Salt)追加:平文の特定位置にランダムな文字列を挿入してからMD5化
- 暗号化後の文字列並び替え:まず平文をMD5で暗号化し、その結果の文字列を並び替える
基本的な方針は、データベースが侵害されても、正しい平文を復元できないようにすることです。
ネットワークデータ暗号化戦略
- 暗号化対象:プライバシー情報(パスワード、銀行情報など)
- 暗号化方案
- プライバシー情報は必ずPOSTリクエストで送信
- MD5などの暗号化アルゴリズムを使用してデータを暗号化
- 暗号化強化:復元の難易度を高めるため
- 平文に対する2重MD5:MD5(MD5(pass))
- まず平文にソルトを追加し、MD5化:MD5(pass.$salt)
ローカルストレージの暗号化
- 暗号化対象:重要なデータ(例:ゲームデータ)
コードセキュリティの問題
- リバースエンジニアリング
- 現在、ツールや技術を用いてソースコードを逆コンパイル可能
- 逆コンパイルすると純粋なC言語のコードになり、可読性は低い
- 少なくとも使用されているフレームワークの特定は可能
- 参考書籍:『iOSリバースエンジニアリング』
- 解決策:リリース前にコードを難読化
- 難読化前:
@interface HMPerson :NSObject - (void)run; - (void)eat; @end
- 難読化後:
@interface A :NSObject - (void)a; - (void)b; @end
- 難読化前:
MD5暗号化の実装例
暗号化ファイルのインポート
#import "ViewController.h"
#import "MBProgressHUD.h"
#import "NSString+Hash.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *userIDField;
@property (weak, nonatomic) IBOutlet UITextField *passwordField;
- (IBAction)performLogin;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
- (IBAction)performLogin {
// 1.ユーザー名の確認
NSString *userIDText = self.userIDField.text;
if (userIDText.length == 0) {
[MBProgressHUD showError:@"ユーザー名を入力してください"];
return;
}
// 2.パスワードの確認
NSString *passwordText = self.passwordField.text;
if (passwordText.length == 0) {
[MBProgressHUD showError:@"パスワードを入力してください"];
return;
}
// ローディング表示
[MBProgressHUD showMessage:@"ログイン中...."];
// 3.サーバーにユーザー名とパスワードを送信
NSURL *url = [NSURL URLWithString:@"http://218.83.161.124:8080/job/login"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.timeoutInterval = 15;
request.HTTPMethod = @"POST";
// パスワードの暗号化
passwordText = [self obfuscatedMD5:passwordText];
// リクエストボディの設定
NSString *param = [NSString stringWithFormat:@"username=%@&pwd=%@", userIDText, passwordText];
request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];
// ヘッダー情報の設定
[request setValue:@"iPhone 6" forHTTPHeaderField:@"User-Agent"];
// 非同期リクエストの送信
NSOperationQueue *queue = [NSOperationQueue mainQueue];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:
^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// ローディング非表示
[MBProgressHUD hideHUD];
if (connectionError || data == nil) {
[MBProgressHUD showError:@"リクエスト失敗"];
return;
}
// サーバーからのJSONレスポンスの解析
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSString *errorMessage = responseDict[@"error"];
if (errorMessage) {
[MBProgressHUD showError:errorMessage];
} else {
NSString *successMessage = responseDict[@"success"];
[MBProgressHUD showSuccess:successMessage];
}
}];
}
/**
* MD5($pass.$salt) の実装
*
* @param input 平文
* @return 暗号化された文字列
*/
- (NSString *)saltedMD5:(NSString *)input
{
// ソルト追加:平文にランダムな文字列を連結
NSString *saltedInput = [input stringByAppendingString:@"aaa"];
return [saltedInput md5String];
}
/**
* MD5(MD5($pass)) の実装
*
* @param input 平文
* @return 二重に暗号化された文字列
*/
- (NSString *)doubleMD5:(NSString *)input
{
return [[input md5String] md5String];
}
/**
* まず暗号化してから文字列を並び替える
*
* @param input 平文
* @return 暗号化・並び替え済みの文字列
*/
- (NSString *)obfuscatedMD5:(NSString *)input
{
NSString *hashedPassword = [input md5String];
// ハッシュ値の分割
NSString *prefix = [hashedPassword substringFromIndex:2];
NSString *suffix = [hashedPassword substringToIndex:2];
// 並び替え
NSString *result = [prefix stringByAppendingString:suffix];
NSLog(@"\ninput=%@\nhashed=%@\nresult=%@", input, hashedPassword, result);
return result;
}
@end