...
private bool CertificateCheck(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
...
return true;
}
...
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create("https://www.myTrustedSite.com");
webRequest.ServerCertificateValidationCallback = CertificateCheck;
WebResponse response = webRequest.GetResponse();
...
...
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback);
...
...
config := &tls.Config{
// Set InsecureSkipVerify to skip the default validation
InsecureSkipVerify: true,
...
}
conn, err := tls.Dial("tcp", "example.com:443", conf)
..
...
Email email = new SimpleEmail();
email.setHostName("smtp.servermail.com");
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true);
email.setFrom("user@gmail.com");
email.setSubject("TestMail");
email.setMsg("This is a test mail ... :-)");
email.addTo("foo@bar.com");
email.send();
...
smtp.mailserver.com:465
に接続しようとすると、このアプリケーションは "hackedserver.com
" に発行された証明書を容易に受け入れます。これによりアプリケーションは、ハッキングされているサーバーへの不正な SSL 接続によって、機密性の高いユーザー情報をリークさせる可能性があります。
...
var options = {
key : fs.readFileSync('my-server-key.pem'),
cert : fs.readFileSync('server-cert.pem'),
requestCert: true,
...
}
https.createServer(options);
...
https.Server
オブジェクトが作成されるとき、設定 requestCert
は true
に指定されますが rejectUnauthorized
は指定されずにデフォルトの false
になります。つまり、サーバーは SSL を介してクライアントを検証するように作成されましたが、証明書が提供されている CA のリストで承認されていない場合にも接続が受け入れられます。
var tls = require('tls');
...
tls.connect({
host: 'https://www.hackersite.com',
port: '443',
...
rejectUnauthorized: false,
...
});
rejectUnauthorized
が False に設定されたので、権限のない証明書が受け入れられ、未確認のサーバーとのセキュアな接続が引き続き作成されることを意味します。アプリケーションは、ハッキングされているサーバーへの不正な SSL 接続によって、ユーザー機密情報をリークさせる可能性があります。NSURLConnectionDelegate
を設定します。
implementation NSURLRequest (IgnoreSSL)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
@end
Example 1
の NSURLRequest
の実装を使用して SSL によりセキュリティ保護されるサーバーに接続するとき、リクエストされたサーバーの証明書が自己署名されている (これにより検証されない) 場合は警告やエラーが発生しません。これにより、アプリケーションはユーザーの機密情報を不正な SSL 接続によって漏洩する可能性があります。
...
import ssl
ssl_sock = ssl.wrap_socket(s)
...
require 'openssl'
...
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode=OpenSSL::SSL::VERIFY_NONE
...
NSURLConnectionDelegate
を設定します。
class Delegate: NSObject, NSURLConnectionDelegate {
...
func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace?) -> Bool {
return protectionSpace?.authenticationMethod == NSURLAuthenticationMethodServerTrust
}
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) {
challenge.sender?.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge)
challenge.sender?.continueWithoutCredentialForAuthenticationChallenge(challenge)
}
}
Example 1
の NSURLConnectionDelegate
の実装を使用して SSL によりセキュリティ保護されるサーバーに接続するとき、リクエストされたサーバーの証明書が自己署名されている (これにより検証されない) 場合は警告やエラーが発生しません。これにより、アプリケーションはユーザーの機密情報を不正な SSL 接続によって漏洩する可能性があります。NSURLSession
クラスでは、SSL/TLS チェーンの検証はアプリケーションの認証委任メソッドによって処理されます。ただし、認証情報を提供してサーバーに対してユーザー (またはアプリケーション) を認証するのではなく、SSL/TLS ハンドシェイク時にサーバーが提供する認証情報をアプリケーションが確認して、URL ローディング システムにそれらの認証情報を許可すべきか拒否すべきかを通知します。次のコードは、サーバー検証を事実上回避し、セッションの認証情報として受け取ったチャレンジの proposedCredential
を渡すだけの NSURLSessionDelgate
を示しています。
class MySessionDelegate : NSObject, NSURLSessionDelegate {
...
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
...
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, challenge.proposedCredential)
...
}
...
}
allowBackup
属性を true
(デフォルト値) に設定し、<application>
タグの backupAgent
属性を定義することで行えます。Environment.getExternalStorageDirectory()
が Android デバイスの外部ストレージに参照を返しています。private void WriteToFile(String what_to_write) {
try{
File root = Environment.getExternalStorageDirectory();
if(root.canWrite()) {
File dir = new File(root + "write_to_the_SDcard");
File datafile = new File(dir, number + ".extension");
FileWriter datawriter = new FileWriter(datafile);
BufferedWriter out = new BufferedWriter(datawriter);
out.write(what_to_write);
out.close();
}
}
}
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:ThisDeviceOnly
を含まないアクセシビリティ レベルでは、暗号化されていないバックアップを使用する場合でも、iCloud および iTunes にバックアップされ、どのデバイスにもリストアできます。格納されているデータがどれだけ機密性が高く個人的かによっては、プライバシーの問題が発生する可能性があります。
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleWhenUnlocked forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:ThisDeviceOnly
を含まないアクセシビリティ レベルでは、暗号化されていないバックアップを使用する場合でも、iCloud および iTunes にバックアップされ、どのデバイスにもリストアできます。格納されているデータがどれだけ機密性が高く個人的かによっては、プライバシーの問題が発生する可能性があります。
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlocked
SecItemAdd(query as CFDictionary, nil)
...
protected void onCreate(Bundle savedInstanceState) {
...
try {
File httpCacheDir = new File(context.getExternalCacheDir(), "http");
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
HttpResponseCache.install(httpCacheDir, httpCacheSize);
} catch (IOException e) {
Log.i(TAG, "HTTP response cache installation failed:" + e);
}
}
protected void onStop() {
...
HttpResponseCache cache = HttpResponseCache.getInstalled();
if (cache != null) {
cache.flush();
}
}
{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
ファイルに暗号化せずに格納します。{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
ファイルに暗号化せずに格納します。{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
ファイルに暗号化せずに格納します。 URLCache
クラスの diskCapacity
または memoryCapacity
プロパティを 0 に設定することで、HTTP(S) レスポンス キャッシュ システムを効果的に無効化できると考えるかもしれません。しかし、NSURLCache
ドキュメントには、デバイスのメモリまたはディスク領域が残り少なくなった場合のみ、ディスク上のキャッシュとメモリ内のキャッシュの両方が設定されたサイズまで切り詰められると記載されています。両方の設定は、セキュリティ制御としてではなく、システム リソースを解放してパフォーマンスを向上させるために使用されます。{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
ファイルに暗号化せずに格納します。 URLCache
クラスの diskCapacity
または memoryCapacity
プロパティを 0 に設定することで、HTTP(S) レスポンス キャッシュ システムを効果的に無効化できると考えるかもしれません。しかし、NSURLCache
ドキュメントには、デバイスのメモリまたはディスク領域が残り少なくなった場合のみ、ディスク上のキャッシュとメモリ内のキャッシュの両方が設定されたサイズまで切り詰められると記載されています。両方の設定は、セキュリティ制御としてではなく、システム リソースを解放してパフォーマンスを向上させるために使用されます。NSFileManager
に定数として定義されます。つまり、NSFileManager
インスタンスと関連付けられた NSDictionary
に NSFileProtectionKey
鍵の値として割り当てられることになります。またファイルを作成するか、あるいは setAttributes:ofItemAtPath:error:
、attributesOfItemAtPath:error:
、createFileAtPath:contents:attributes:
などの NSFileManager
関数を使用して変更されるデータ保護クラスをファイルに含めることができます。さらに、対応するデータ保護定数は NSData
オブジェクトに NSDataWritingOptions
として定義され、これを options
引数として NSData
関数 writeToURL:options:error:
および writeToFile:options:error:
に渡すことができます。NSFileManager
および NSData
の各種データ保護クラス定数の定義を以下に示します。NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
または NSFileProtectionCompleteUntilFirstUserAuthentication
でマーキングすると、ユーザーのパスワードとデバイスの UID から導出された鍵を使用してファイルを暗号化できる一方、データは特定の状況下でアクセス可能のままになります。このように、NSFileProtectionCompleteUnlessOpen
または NSFileProtectionCompleteUntilFirstUserAuthentication
の使用方法については慎重に検証し、今後も NSFileProtectionComplete
による保護が保証されるかどうかを見極める必要があります。例 2: 以下の例では、所定のデータはユーザーがデバイスの電源をオンにして初回のパスワードを入力するまでに限り保護されます (次の再起動まで)。
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSDictionary *protection = [NSDictionary dictionaryWithObject:NSFileProtectionCompleteUntilFirstUserAuthentication forKey:NSFileProtectionKey];
...
[[NSFileManager defaultManager] setAttributes:protection ofItemAtPath:filepath error:nil];
...
BOOL ok = [testToWrite writeToFile:filepath atomically:YES encoding:NSUnicodeStringEncoding error:&err];
...
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSData *textData = [textToWrite dataUsingEncoding:NSUnicodeStingEncoding];
...
BOOL ok = [textData writeToFile:filepath options:NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication error:&err];
...
NSFileManager
に定数として定義されます。つまり、NSFileManager
インスタンスと関連付けられた Dictionary
に NSFileProtectionKey
鍵の値として割り当てられることになります。またファイルを作成するか、あるいは setAttributes(_:ofItemAtPath:)
、attributesOfItemAtPath(_:)
、createFileAtPath(_:contents:attributes:)
などの NSFileManager
関数を使用して変更されるデータ保護クラスをファイルに含めることができます。さらに、対応するデータ保護定数は NSData
オブジェクトに NSDataWritingOptions
列挙型として定義されています。これは options
引数として NSData
の関数 (
writeToFile(_:options:)
など) に渡すことができます。NSFileManager
および NSData
の各種データ保護クラス定数の定義を以下に示します。NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
または NSFileProtectionCompleteUntilFirstUserAuthentication
でマーキングすると、ユーザーのパスワードとデバイスの UID から導出された鍵を使用してファイルを暗号化できる一方、データは特定の状況下でアクセス可能のままになります。このように、NSFileProtectionCompleteUnlessOpen
または NSFileProtectionCompleteUntilFirstUserAuthentication
の使用方法については慎重に検証し、今後も NSFileProtectionComplete
による保護が保証されるかどうかを見極める必要があります。例 2: 以下の例では、所定のデータはユーザーがデバイスの電源をオンにして初回のパスワードを入力するまでに限り保護されます (次の再起動まで)。
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
let protection = [NSFileProtectionKey: NSFileProtectionCompleteUntilFirstUserAuthentication]
do {
try NSFileManager.defaultManager().setAttributes(protection, ofItemAtPath: filename)
} catch let error as NSError {
NSLog("Unable to change attributes: \(error.debugDescription)")
}
...
BOOL ok = textToWrite.writeToFile(filename, atomically:true)
...
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
...
BOOL ok = textData.writeToFile(filepath, options: .DataWritingFileProtectionCompleteUntilFirstUserAuthentication);
...
kSecAttrAccessible
キーの値として割り当てる必要があります。さまざまなキーチェーン アクセシビリティ定数の定義を以下に示します。kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
でマーキングすると、ユーザーのパスコードとデバイスの UID から導出された鍵を使用してファイルを暗号化できる一方、データは特定の状況下でアクセス可能のままになります。このように、kSecAttrAccessibleAfterFirstUnlock
の使用方法については慎重に検証し、今後も保護が保証されるかどうかを見極める必要があります。
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlock forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessible
キーの値として割り当てる必要があります。さまざまなキーチェーン アクセシビリティ定数の定義を以下に示します。kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
でマーキングすると、ユーザーのパスコードとデバイスの UID から導出された鍵を使用してファイルを暗号化できる一方、データは特定の状況下でアクセス可能のままになります。このように、kSecAttrAccessibleAfterFirstUnlock
の使用方法については慎重に検証し、今後も保護が保証されるかどうかを見極める必要があります。
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlock
SecItemAdd(query as CFDictionary, nil)
...
NSFileManager
に定数として定義されます。つまり、NSFileManager
インスタンスと関連付けられた NSDictionary
に NSFileProtectionKey
鍵の値として割り当てられることになります。またファイルを作成するか、あるいは setAttributes:ofItemAtPath:error:
、attributesOfItemAtPath:error:
、createFileAtPath:contents:attributes:
などの NSFileManager
関数を使用して変更されるデータ保護クラスをファイルに含めることができます。さらに、対応するデータ保護定数は NSData
オブジェクトに NSDataWritingOptions
として定義され、これを options
引数として NSData
関数 writeToURL:options:error:
および writeToFile:options:error:
に渡すことができます。NSFileManager
および NSData
の各種データ保護クラス定数の定義を以下に示します。NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionNone
を指定すると、デバイスの UID のみに基づいて導出された鍵が暗号化に使用されます。これにより、デバイスの電源が入っているときはパスワードでロックされているときや起動時を含み、これらのファイルが常にアクセス可能になります。このため、NSFileProtectionNone
の使用については慎重に検証し、今後もより厳格なデータ保護クラスによる保護が保証されることを見極める必要があります。例 2: 次の例では、所定のデータが保護されていません (デバイスの電源がオンのとき常にアクセス可能)。
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSDictionary *protection = [NSDictionary dictionaryWithObject:NSFileProtectionNone forKey:NSFileProtectionKey];
...
[[NSFileManager defaultManager] setAttributes:protection ofItemAtPath:filepath error:nil];
...
BOOL ok = [testToWrite writeToFile:filepath atomically:YES encoding:NSUnicodeStringEncoding error:&err];
...
...
filepath = [self.GetDocumentDirectory stringByAppendingPathComponent:self.setFilename];
...
NSData *textData = [textToWrite dataUsingEncoding:NSUnicodeStingEncoding];
...
BOOL ok = [textData writeToFile:filepath options:NSDataWritingFileProtectionNone error:&err];
...
NSFileManager
インスタンスに関連付けられた Dictionary
で NSFileProtectionKey
キーの値として割り当てるために、NSFileManager
で定数として定義されています。setAttributes(_:ofItemAtPath:)
、attributesOfItemAtPath(_:)
、createFileAtPath(_:contents:attributes:)
などの NSFileManager
の関数を使用すると、ファイルの作成やデータ保護クラスの変更を行うことができます。さらに、対応するデータ保護定数は NSData
オブジェクトに NSDataWritingOptions
列挙型として定義されています。これは options
引数として NSData
の関数 (
writeToFile(_:options:)
など) に渡すことができます。NSFileManager
および NSData
の各種データ保護クラス定数の定義を以下に示します。NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionNone
を指定すると、デバイスの UID のみに基づいて導出された鍵が暗号化に使用されます。これにより、デバイスの電源が入っているときはパスワードでロックされているときや起動時を含み、これらのファイルが常にアクセス可能になります。このため、NSFileProtectionNone
の使用については慎重に検証し、今後もより厳格なデータ保護クラスによる保護が保証されることを見極める必要があります。例 2: 次の例では、所定のデータが保護されていません (デバイスの電源がオンのとき常にアクセス可能)。
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
let protection = [NSFileProtectionKey: NSFileProtectionNone]
do {
try NSFileManager.defaultManager().setAttributes(protection, ofItemAtPath: filename)
} catch let error as NSError {
NSLog("Unable to change attributes: \(error.debugDescription)")
}
...
BOOL ok = textToWrite.writeToFile(filename, atomically:true)
...
...
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let filename = "\(documentsPath)/tmp_activeTrans.txt"
...
BOOL ok = textData.writeToFile(filepath, options: .DataWritingFileProtectionNone);
...
kSecAttrAccessible
キーの値として割り当てる必要があります。さまざまなキーチェーン アクセシビリティ定数の定義を以下に示します。kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
を指定すると、デバイスの UID のみに基づいて導出された鍵が暗号化に使用されます。これにより、デバイスの電源が入っているときはパスワードでロックされているときや起動時を含み、これらのファイルが常にアクセス可能になります。このため、kSecAttrAccessibleAlways
の使用については慎重に検証し、今後もより厳格なキーチェーン アクセシビリティ レベルによる保護が保証されることを見極める必要があります。
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleAlways forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessible
キーの値として割り当てる必要があります。さまざまなキーチェーン アクセシビリティ定数の定義を以下に示します。kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
を指定すると、デバイスの UID のみに基づいて導出された鍵が暗号化に使用されます。これにより、デバイスの電源が入っているときはパスワードでロックされているときや起動時を含み、これらのファイルが常にアクセス可能になります。このため、kSecAttrAccessibleAlways
の使用については慎重に検証し、今後もより厳格なキーチェーン アクセシビリティ レベルによる保護が保証されることを見極める必要があります。
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleAlways
SecItemAdd(query as CFDictionary, nil)
...
Realm
データベースへの接続を確立します。
Realm realm = Realm.getDefaultInstance();
Realm
データベースへの接続を確立します。
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
Realm
データベースへの接続を確立します。
let realm = try! Realm()
UIImageWriteToSavedPhotosAlbum
を使用して画像をフォト アルバムに保存します。
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Access the uncropped image from info dictionary
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Save image
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
...
}
UIImageWriteToSavedPhotosAlbum
を使用して画像をフォト アルバムに保存します。
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
}
// Save image
UIImageWriteToSavedPhotosAlbum(pickedImage!, self, nil, nil)
dismissViewControllerAnimated(true, completion: nil)
}
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
のような合理的にセキュアなポリシーで格納される場合、デバイスが盗まれ、パスコードが設定されていた場合、盗んだ人はキーチェーン アイテムを復号化するためにデバイスをロック解除する必要があります。正しいパスコードを入力できない場合、盗んだ人はキーチェーン アイテムを復号化できません。ただし、パスコードが設定されていない場合、攻撃者は指をスライドさせるだけでデバイスをロック解除し、キーチェーン アイテムを復号化できます。このため、デバイスでのパスコードの設定を強制できない場合、キーチェーン暗号化メカニズムが脆弱になる可能性があります。
...
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSData *token = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
// Configure KeyChain Item
[dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id) kSecClass];
[dict setObject:token forKey:(__bridge id)kSecValueData];
...
[dict setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id) kSecAttrAccessible];
OSStatus error = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
...
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
のような合理的にセキュアなポリシーで格納される場合、デバイスが盗まれ、パスコードが設定されていた場合、盗んだ人はキーチェーン アイテムを復号化するためにデバイスをロック解除する必要があります。正しいパスコードを入力できない場合、盗んだ人はキーチェーン アイテムを復号化できません。ただし、パスコードが設定されていない場合、攻撃者は指をスライドさせるだけでデバイスをロック解除し、キーチェーン アイテムを復号化できます。このため、デバイスでのパスコードの設定を強制できない場合、キーチェーン暗号化メカニズムが脆弱になる可能性があります。
...
// Configure KeyChain Item
let token = "secret"
var query = [String : AnyObject]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecValueData as String] = token as AnyObject?
...
query[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
SecItemAdd(query as CFDictionary, nil)
...
setPersistent:YES
を呼び出すことで永続的なものとして構成されます。
...
UIPasteboard *pasteboard = [UIPasteboard pasteboardWithName:@"myPasteboard" create:YES];
[pasteboard setPersistent:YES];
...
setPersistent(true)
を呼び出すことで永続的なものとして構成されます。
...
let pasteboard = UIPasteboard(name: UIPasteboard.Name(rawValue: "myPasteboard"), create: true)!
pasteboard.setPersistent(true)
...
foo
バケットへの完全な匿名アクセス権を付与する Access Control Policy
を設定します。
GetBucketAclRequest bucketAclReq = GetBucketAclRequest.builder().bucket("foo").build();
GetBucketAclResponse getAclRes = s3.getBucketAcl(bucketAclReq);
List<Grant> grants = getAclRes.grants();
Grantee allusers = Grantee.builder().uri("http://acs.amazonaws.com/groups/global/AllUsers").build();
Permission fc_permission = Permission.fromValue("FullControl");
Grant grant = Grant.builder().grantee(allusers).permission(fc_permission).build();
grants.add(grant);
AccessControlPolicy acl = AccessControlPolicy.builder().grants(grants).build();
foo
バケットへ匿名の ACP 読み取りアクセス権を付与する Access Control Policy
を設定します。
GetBucketAclRequest bucketAclReq = GetBucketAclRequest.builder().bucket("foo").build();
GetBucketAclResponse getAclRes = s3.getBucketAcl(bucketAclReq);
List<Grant> grants = getAclRes.grants();
Grantee allusers = Grantee.builder().uri("http://acs.amazonaws.com/groups/global/AllUsers").build();
Permission fc_permission = Permission.fromValue("READ_ACP");
Grant grant = Grant.builder().grantee(allusers).permission(fc_permission).build();
grants.add(grant);
AccessControlPolicy acl = AccessControlPolicy.builder().grants(grants).build();
foo
バケットへの匿名の読み取りアクセス権を付与する Access Control Policy
を設定します。
GetBucketAclRequest bucketAclReq = GetBucketAclRequest.builder().bucket("foo").build();
GetBucketAclResponse getAclRes = s3.getBucketAcl(bucketAclReq);
List<Grant> grants = getAclRes.grants();
Grantee allusers = Grantee.builder().uri("http://acs.amazonaws.com/groups/global/AllUsers").build();
Permission fc_permission = Permission.fromValue("Read");
Grant grant = Grant.builder().grantee(allusers).permission(fc_permission).build();
grants.add(grant);
AccessControlPolicy acl = AccessControlPolicy.builder().grants(grants).build();
foo
バケットへ匿名の ACP 書き込みアクセス権を付与する Access Control Policy
を設定します。
GetBucketAclRequest bucketAclReq = GetBucketAclRequest.builder().bucket("foo").build();
GetBucketAclResponse getAclRes = s3.getBucketAcl(bucketAclReq);
List<Grant> grants = getAclRes.grants();
Grantee allusers = Grantee.builder().uri("http://acs.amazonaws.com/groups/global/AllUsers").build();
Permission fc_permission = Permission.fromValue("WRITE_ACP");
Grant grant = Grant.builder().grantee(allusers).permission(fc_permission).build();
grants.add(grant);
AccessControlPolicy acl = AccessControlPolicy.builder().grants(grants).build();
foo
バケットへの匿名の書き込みアクセス権を付与する Access Control Policy
を設定します。
GetBucketAclRequest bucketAclReq = GetBucketAclRequest.builder().bucket("foo").build();
GetBucketAclResponse getAclRes = s3.getBucketAcl(bucketAclReq);
List<Grant> grants = getAclRes.grants();
Grantee allusers = Grantee.builder().uri("http://acs.amazonaws.com/groups/global/AllUsers").build();
Permission fc_permission = Permission.fromValue("Write");
Grant grant = Grant.builder().grantee(allusers).permission(fc_permission).build();
grants.add(grant);
AccessControlPolicy acl = AccessControlPolicy.builder().grants(grants).build();