...
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
, esta aplicación aceptaría sin objeciones cualquier certificado emitido a "hackedserver.com
". La aplicación podría filtrar entonces información de usuario confidencial en una conexión SSL interrumpida en el servidor pirateado.
...
var options = {
key : fs.readFileSync('my-server-key.pem'),
cert : fs.readFileSync('server-cert.pem'),
requestCert: true,
...
}
https.createServer(options);
...
https.Server
, el parámetro requestCert
se define como true
, pero no se establece rejectUnauthorized
, lo que establece false
de forma predeterminada. Esto significa que, aunque el servidor se creó con la intención de verificar clientes en SSL, se seguirán aceptando conexiones incluso si el certificado no está autorizado con la lista de entidades de certificación proporcionadas.
var tls = require('tls');
...
tls.connect({
host: 'https://www.hackersite.com',
port: '443',
...
rejectUnauthorized: false,
...
});
rejectUnauthorized
se estableció en el valor false, significa que se aceptarán certificados no autorizados y que de todas formas se creará una conexión segura con el servidor no identificado. La aplicación podría filtrar entonces información de usuario confidencial en una conexión SSL interrumpida en el servidor pirateado.NSURLConnectionDelegate
para que acepte cualquier certificado HTTPS:
implementation NSURLRequest (IgnoreSSL)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
return YES;
}
@end
NSURLRequest
del Example 1
, no aparecerá ningún error o advertencia si el certificado del servidor que recibe la solicitud se ha firmado automáticamente (y, por lo tanto, no está verificado). Como resultado, la aplicación podría filtrar entonces información de usuario confidencial en una conexión SSL interrumpida.
...
import ssl
ssl_sock = ssl.wrap_socket(s)
...
require 'openssl'
...
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode=OpenSSL::SSL::VERIFY_NONE
...
NSURLConnectionDelegate
para que acepte cualquier certificado HTTPS:
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)
}
}
NSURLConnectionDelegate
del Example 1
, no aparecerá ningún error o advertencia si el certificado del servidor que recibe la solicitud se ha firmado automáticamente (y, por lo tanto, no está verificado). Como resultado, la aplicación podría filtrar entonces información de usuario confidencial en una conexión SSL interrumpida.NSURLSession
, la validación de la cadena SSL/TLS se controla a través del método de delegación de autenticación de la aplicación, pero en lugar de proporcionar al servidor las credenciales para autenticar al usuario (o aplicación), la aplicación comprueba las credenciales que proporciona el servidor durante el intercambio SSL/TLS e indica al sistema de carga de URL si debe aceptar o rechazar esas credenciales. El siguiente código muestra un NSURLSessionDelgate
que devuelve la proposedCredential
del desafío recibido como una credencial para la sesión, lo que en la práctica permite eludir la verificación del servidor:
class MySessionDelegate : NSObject, NSURLSessionDelegate {
...
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
...
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, challenge.proposedCredential)
...
}
...
}
allowBackup
en true
(el valor predeterminado) y defina el atributo backupAgent
en la etiqueta <application>
.Environment.getExternalStorageDirectory()
devuelve una referencia al almacenamiento externo del dispositivo 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
se les hará una copia de seguridad en iCloud y en iTunes incluso si se usan copias de seguridad sin cifrar que pueden restaurarse en cualquier dispositivo. Según el nivel de confidencialidad y privacidad de los datos almacenados, esto puede suponer un problema de privacidad.
...
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
se les hará una copia de seguridad en iCloud y en iTunes incluso si se usan copias de seguridad sin cifrar que pueden restaurarse en cualquier dispositivo. Según el nivel de confidencialidad y privacidad de los datos almacenados, esto puede suponer un problema de privacidad.
...
// 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*
. diskCapacity
o memoryCapacity
de la clase URLCache
en 0, deshabilitan realmente el sistema de caché de respuesta de HTTP(S). Sin embargo, la documentación de NSURLCache
indica que tanto la caché del disco como la de la memoria se truncarán en los tamaños configurados únicamente si al dispositivo le queda poca memoria o poco espacio en disco. Ambas configuraciones están diseñadas para que el sistema libere recursos del sistema y mejore el rendimiento, no como un control de seguridad.{app ID}/Library/Caches/com.mycompany.myapp/Cache.db*
. diskCapacity
o memoryCapacity
de la clase URLCache
en 0, deshabilitan realmente el sistema de caché de respuesta de HTTP(S). Sin embargo, la documentación de NSURLCache
indica que tanto la caché del disco como la de la memoria se truncarán en los tamaños configurados únicamente si al dispositivo le queda poca memoria o poco espacio en disco. Ambas configuraciones están diseñadas para que el sistema libere recursos del sistema y mejore el rendimiento, no como un control de seguridad.NSFileManager
como constantes que deben asignarse como el valor de la clave NSFileProtectionKey
en un NSDictionary
asociado a la instancia de NSFileManager
, y se pueden crear archivos o modificar su clase de protección de datos mediante el uso de funciones NSFileManager
como setAttributes:ofItemAtPath:error:
, attributesOfItemAtPath:error:
y createFileAtPath:contents:attributes:
. Además, las constantes de protección de datos correspondientes se definen para objetos NSData
como NSDataWritingOptions
que pueden pasarse como el argumento options
a las funciones NSData
writeToURL:options:error:
y writeToFile:options:error:
. Las definiciones de las diversas constantes de clases de protección de datos para NSFileManager
y NSData
son las siguientes:NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
o NSFileProtectionCompleteUntilFirstUserAuthentication
, se podrá cifrar con una clave derivada del código de acceso del usuario y del UID del dispositivo, los datos seguirán siendo accesibles en determinadas circunstancias. Por lo tanto, deben revisarse con atención los usos de NSFileProtectionCompleteUnlessOpen
o NSFileProtectionCompleteUntilFirstUserAuthentication
para determinar si se necesita mayor protección con NSFileProtectionComplete
.Ejemplo 2: en el siguiente ejemplo, los datos solo están protegidos hasta que el usuario enciende el dispositivo y proporciona el código de acceso por primera vez (hasta que vuelva a reiniciarse):
...
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
como constantes que deben asignarse como el valor de la clave NSFileProtectionKey
en un Dictionary
asociado a la instancia de NSFileManager
, y se pueden crear archivos o modificar su clase de protección de datos mediante el uso de funciones NSFileManager
como setAttributes(_:ofItemAtPath:)
, attributesOfItemAtPath(_:)
y createFileAtPath(_:contents:attributes:)
. Además, se definen las constantes de protección de datos correspondientes para objetos NSData
en la enumeración NSDataWritingOptions
que pueden pasarse como el argumento options
a funciones NSData
writeToFile(_:options:)
. Las definiciones de las diversas constantes de clases de protección de datos para NSFileManager
y NSData
son las siguientes:NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionCompleteUnlessOpen
o NSFileProtectionCompleteUntilFirstUserAuthentication
, se podrá cifrar con una clave derivada del código de acceso del usuario y del UID del dispositivo, los datos seguirán siendo accesibles en determinadas circunstancias. Por lo tanto, deben revisarse con atención los usos de NSFileProtectionCompleteUnlessOpen
o NSFileProtectionCompleteUntilFirstUserAuthentication
para determinar si se necesita mayor protección con NSFileProtectionComplete
.Ejemplo 2: en el siguiente ejemplo, los datos determinados solo están protegidos hasta que el usuario enciende el dispositivo y proporciona el código de acceso por primera vez (hasta el siguiente reinicio).
...
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
en el diccionario de atributos de las claves. Las definiciones de las diversas constantes de accesibilidad de las claves son las siguientes:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
se podrá cifrar con una clave derivada del código de acceso del usuario y del UID del dispositivo, los datos seguirán siendo accesibles en determinadas circunstancias. Por lo tanto, deben revisarse con atención los usos de kSecAttrAccessibleAfterFirstUnlock
para determinar si se necesita mayor protección.
...
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
en el diccionario de atributos de las claves. Las definiciones de las diversas constantes de accesibilidad de las claves son las siguientes:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAfterFirstUnlock
se podrá cifrar con una clave derivada del código de acceso del usuario y del UID del dispositivo, los datos seguirán siendo accesibles en determinadas circunstancias. Por lo tanto, deben revisarse con atención los usos de kSecAttrAccessibleAfterFirstUnlock
para determinar si se necesita mayor protección.
...
// 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
como constantes que deben asignarse como el valor de la clave NSFileProtectionKey
en un NSDictionary
asociado a la instancia de NSFileManager
, y se pueden crear archivos o modificar su clase de protección de datos mediante el uso de funciones NSFileManager
como setAttributes:ofItemAtPath:error:
, attributesOfItemAtPath:error:
y createFileAtPath:contents:attributes:
. Además, las constantes de protección de datos correspondientes se definen para objetos NSData
como NSDataWritingOptions
que pueden pasarse como el argumento options
a las funciones NSData
writeToURL:options:error:
y writeToFile:options:error:
. Las definiciones de las diversas constantes de clases de protección de datos para NSFileManager
y NSData
son las siguientes:NSFileProtectionComplete
, NSDataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingFileProtectionNone
:NSFileProtectionNone
provoca un cifrado con una clave derivada exclusivamente del UID del dispositivo. Esto permite que se pueda acceder a dichos archivos siempre que el dispositivo está encendido, incluso cuando está bloqueado con un código de acceso o durante el arranque. Por lo tanto, deben revisarse con atención los usos de NSFileProtectionNone
para determinar si se necesita mayor protección con una clase de protección de datos más estricta.Ejemplo 2: en el siguiente ejemplo, los datos no están protegidos (son accesibles en todo momento cuando el dispositivo está encendido):
...
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
como constantes que deben asignarse como el valor de la clave NSFileProtectionKey
en un Dictionary
asociado a la instancia de NSFileManager
. Se pueden crear archivos o modificar su clase de protección de datos mediante el uso de funciones NSFileManager
como setAttributes(_:ofItemAtPath:)
, attributesOfItemAtPath(_:)
y createFileAtPath(_:contents:attributes:)
. Además, se definen constantes de protección de datos correspondientes para objetos NSData
en la enumeración NSDataWritingOptions
que pueden pasarse como el argumento options
a funciones NSData
como
writeToFile(_:options:)
. Las definiciones de las diversas constantes de clases de protección de datos para NSFileManager
y NSData
son las siguientes:NSFileProtectionComplete
, NSDataWritingOptions.DataWritingFileProtectionComplete
:NSFileProtectionCompleteUnlessOpen
, NSDataWritingOptions.DataWritingFileProtectionCompleteUnlessOpen
:NSFileProtectionCompleteUntilFirstUserAuthentication
, NSDataWritingOptions.DataWritingFileProtectionCompleteUntilFirstUserAuthentication
:NSFileProtectionNone
, NSDataWritingOptions.DataWritingFileProtectionNone
:NSFileProtectionNone
provoca un cifrado con una clave derivada exclusivamente del UID del dispositivo. Esto permite que se pueda acceder a dichos archivos siempre que el dispositivo está encendido, incluso cuando está bloqueado con un código de acceso o durante el arranque. Por lo tanto, deben revisarse con atención los usos de NSFileProtectionNone
para determinar si se necesita mayor protección con una clase de protección de datos más estricta.Ejemplo 2: en el siguiente ejemplo, los datos determinados no están protegidos (es decir, son accesibles en todo momento cuando el dispositivo está encendido).
...
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
en el diccionario de atributos de las claves. Las definiciones de las diversas constantes de accesibilidad de las claves son las siguientes:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
provoca un cifrado con una llave derivada exclusivamente del UID del dispositivo. Esto permite que se pueda acceder a dichos archivos siempre que el dispositivo está encendido, incluso cuando está bloqueado con un código de acceso o durante el arranque. Por lo tanto, deben revisarse con atención los usos de kSecAttrAccessibleAlways
para determinar si se necesita mayor protección con un nivel de accesibilidad de las llaves más estricto.
...
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
en el diccionario de atributos de las claves. Las definiciones de las diversas constantes de accesibilidad de las claves son las siguientes:kSecAttrAccessibleAfterFirstUnlock
:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
:kSecAttrAccessibleAlways
:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
:kSecAttrAccessibleAlwaysThisDeviceOnly
:kSecAttrAccessibleWhenUnlocked
:kSecAttrAccessibleWhenUnlockedThisDeviceOnly
:kSecAttrAccessibleAlways
provoca un cifrado con una llave derivada exclusivamente del UID del dispositivo. Esto permite que se pueda acceder a dichos archivos siempre que el dispositivo está encendido, incluso cuando está bloqueado con un código de acceso o durante el arranque. Por lo tanto, deben revisarse con atención los usos de kSecAttrAccessibleAlways
para determinar si se necesita mayor protección con un nivel de accesibilidad de las llaves más estricto.
...
// 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
sin cifrar:
Realm realm = Realm.getDefaultInstance();
Realm
sin cifrar:
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
Realm
sin cifrar:
let realm = try! Realm()
UIImageWriteToSavedPhotosAlbum
para guardar las imágenes en el álbum de fotos:
- (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
para guardar las imágenes en el álbum de fotos:
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
, si luego roban su dispositivo y se establece un código de acceso, el ladrón deberá desbloquear el dispositivo para descifrar los elementos de las llaves. Si no se introduce el código de acceso correcto, se bloqueará el descifrado de los elementos de las llaves del dispositivo robado. Sin embargo, si no se establece un código de acceso, el atacante solo necesitará deslizar el dedo para desbloquear el dispositivo y obtener las llaves para descifrar sus elementos. Por lo tanto, no exigir un código de acceso en el dispositivo puede debilitar el mecanismo de cifrado de las llaves.
...
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
, si luego roban su dispositivo y se establece un código de acceso, el ladrón deberá desbloquear el dispositivo para descifrar los elementos de las llaves. Si no se introduce el código de acceso correcto, se bloqueará el descifrado de los elementos de las llaves del dispositivo robado. Sin embargo, si no se establece un código de acceso, el atacante solo necesitará deslizar el dedo para desbloquear el dispositivo y obtener las llaves para descifrar sus elementos. Por lo tanto, no exigir un código de acceso en el dispositivo puede debilitar el mecanismo de cifrado de las llaves.
...
// 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)
...
Access Control Policy
que concede acceso anónimo completo al contenedor foo
.
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();
Access Control Policy
que concede un permiso anónimo de lectura de la ACP en el contenedor foo
.
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();
Access Control Policy
que concede acceso anónimo de lectura al contenedor foo
.
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();
Access Control Policy
que concede un permiso anónimo de escritura de la ACP en el contenedor foo
.
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();
Access Control Policy
que concede acceso anónimo de escritura al contenedor foo
.
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();