SlideShare une entreprise Scribd logo
1  sur  84
Dodging Web Crypto API
Landmines
@erniewturner
Finalized! January 2017
WebCrypto API
- W3C
JavaScript API for performing basic cryptographic
operations in web applications, such as hashing,
signature generation and verification, and encryption
and decryption.
@erniewturner
Web Browser ServerIn Transit
Why WebCrypto API
@erniewturner
Web Browser
SSL
ServerIn Transit
Why WebCrypto API
@erniewturner
Cryptographically Strong
PRNG
window.crypto.getRandomValues()
@erniewturner
Subtle Crypto
window.crypto.subtle.*
@erniewturner
It is named SubtleCrypto to reflect the fact that many of these algorithms
have subtle usage requirements in order to provide the required
algorithmic security guarantees. -W3C
It is named SubtleCrypto to reflect the fact that many of these algorithms
have subtle usage requirements in order to provide the required
algorithmic security guarantees. -W3C
Subtle Crypto
Developers making use of the SubtleCrypto interface are expected to be aware of
the security concerns associated with both the design and implementation of the
various algorithms provided. The raw algorithms are provided in order to allow
developers maximum flexibility in implementing a variety of protocols and
applications, each of which may represent the composition and security parameters
in a unique manner that necessitate the use of the raw algorithms.
-MDN
@erniewturner
Subtle Crypto
Methods are generic and take crypto algorithms as strings or objects
Nearly all operations return Promises
Only available over HTTPS
@erniewturner
Subtle Crypto
decrypt
deriveKey
digest
encrypt
exportKey
generateKey
importKey
sign
unwrapKey
verify
wrapKey
@erniewturner
Subtle Crypto
digest
exportKey
generateKey
sign
unwrapKey
verify
wrapKey
@erniewturner
decrypt
deriveKey
encrypt
importKey
Subtle Crypto
RSA
ECDSA
ECDH
SHA
HMAC
@erniewturner
AES
PBKDF2
Subtle Crypto
RSA
ECDSA
ECDH
SHA
HMAC
@erniewturner
AES
PBKDF2
Typed Arrays
Int8Array
Uint8Array
Uint8ClampedArray
Int16Array
Uint16Array
Int32Array
Uint32Array
Float32Array
Float64Array
Array-like view into binary data
@erniewturner
Uint8Array
@erniewturner
10110010100101010100110010101010
Uint8Array
@erniewturner
10110010 10010101 01001100 10101010
Uint8Array
@erniewturner
178 149 76 170
Uint8Array
@erniewturner
178 149 76 170, ,, ][
const empty = new Uint8Array(32);
Uint8Array
[0, 0, 0, ...]
const fixed = new Uint8Array([35, 183, 21, 111]); [35, 183, 21, 111]
const text = UTF8.encode('text'); [116, 101, 120, 116]
const flag = UTF8.encode('!'); [240, 159, 135, 179, 240, 159, 135, 180]
@erniewturner
CryptoKey
@erniewturner
Symmetric Key Algorithm
@erniewturner
AES-256 GCM
DecryptEncrypt
Symmetric
Key
Alice Bob
AES-256 GCM
@erniewturner
256 bit = 32 byte 96 bit = 12 byte
AES-GCM
Crypto Key
Initialization
Vector
Military Grade
AES-256 GCM
PBKDF2
@erniewturner
Password Based Key Derivation Function 2
User
Password
Crypto Key
PBKDF2
SHA-256
User
password
Salt
AES-GCM
Crypto Key
PBKDF2
@erniewturner
Browser Support
Edge
IE
Chrome
Firefox
Safari
PRNG Algorithms
@erniewturner
Typed Arrays
ENCRYPT
Example Project
@erniewturner
……..
Password
Encryption
@erniewturner
User Adds Data
User Enters Password
Convert Password to CryptoKey
Derive AES Key
Encrypt Data
Encrypt
@erniewturner
function encryptData(secretData: string, password: string){
const dataAsBytes = UTF8.encode(secretData);
const passwordAsBytes = UTF8.encode(password);
}
Dat Passcod Derive AES EncryImport
function encryptData(secretData: string, password: string){
const dataAsBytes = UTF8.encode(secretData);
const passwordAsBytes = UTF8.encode(password);
}
function encryptData(secretData: string, password: string){
const dataAsBytes = UTF8.encode(secretData);
const passwordAsBytes = UTF8.encode(password);
}
function encryptData(secretData: string, passwo
const dataAsBytes = UTF8.encode(secretData);
const passwordAsBytes = UTF8.encode(password)
}
Data to Encrypt
byte array form
User Passcode
in binary formbyte array form
User Password Import Key User Passcode
Crypto Key
importKey
@erniewturner
byte array form
@erniewturner
importKey
window.crypto.subtle.importKey(
format: string,
keyData: Uint8Array,
algo: object|string,
extractable: boolean,
usages: string[]
)
function encryptData(secretData: string, password: string){
const dataAsBytes = UT8.encode(secretData);
const passwordAsBytes = UTF8.encode(password);
window.crypto.subtle.importKey(
“raw",
passwordAsBytes,
'PBKDF2',
false
[‘deriveKey’]
)
.then((passwordKey: CryptoKey) => {
});
}
function encryptData(secretData: string, password: string){
const dataAsBytes = UT8.encode(secretData);
const passwordAsBytes = UTF8.encode(password);
window.crypto.subtle.importKey(
“raw",
passwordAsBytes,
'PBKDF2',
false
[‘deriveKey’]
)
.then((passwordKey: CryptoKey) => {
});
}
function encryptData(secretData: string, password: string){
const dataAsBytes = UT8.encode(secretData);
const passwordAsBytes = UTF8.encode(password);
window.crypto.subtle.importKey(
“raw",
passwordAsBytes,
'PBKDF2',
false
[‘deriveKey’]
)
.then((passwordKey: CryptoKey) => {
});
}
function encryptData(secretData: string, passwor
const dataAsBytes = UT8.encode(secretData);
const passwordAsBytes = UTF8.encode(password);
window.crypto.subtle.importKey(
“raw",
passwordAsBytes,
'PBKDF2',
false
[‘deriveKey’]
)
.then((passwordKey: CryptoKey) => {
});
}
Data to Encrypt
byte array form
User Password
Crypto Key
deriveKey
@erniewturner
PBKDF2
SHA-256
User Password
Crypto Key
Salt
AES-GCM
Crypto Key
deriveKey
window.crypto.subtle.deriveKey(
algorithm: object,
masterKey: CryptoKey,
derivedKeyAlgorithm: object,
extractable: boolean,
usages: string[]
)
@erniewturner
.then((passwordKey: CryptoKey) => {
const salt = window.crypto.getRandomValues(new Uint8Array(12));
return window.crypto.subtle.deriveKey({
name: 'PBKDF2',
salt,
iterations: 250000,
hash: {name: 'SHA-256'}
}, passwordKey, {name: 'AES-GCM', length: 256}, false, ['encrypt']);
})
.then((aesKey: CryptoKey) => {
});
.then((passwordKey: CryptoKey) => {
const salt = window.crypto.getRandomValues(new Uint8Array(32));
return window.crypto.subtle.deriveKey({
name: 'PBKDF2',
salt,
iterations: 250000,
hash: {name: 'SHA-256'}
}, passwordKey, {name: 'AES-GCM', length: 256}, false, ['encrypt']);
})
.then((aesKey: CryptoKey) => {
});
.then((passwordKey: CryptoKey) => {
const salt = window.crypto.getRandomValues(new Uint8Array(32));
return window.crypto.subtle.deriveKey({
name: 'PBKDF2',
salt,
iterations: 250000,
hash: {name: 'SHA-256'}
}, passwordKey, {name: 'AES-GCM', length: 256}, false, ['encrypt']);
})
.then((aesKey: CryptoKey) => {
});
.then((passwordKey: CryptoKey) => {
const salt = window.crypto.getRandomValues(new Uint8Array(32));
return window.crypto.subtle.deriveKey({
name: 'PBKDF2',
salt,
iterations: 250000,
hash: {name: 'SHA-256'}
}, passwordKey, {name: 'AES-GCM', length: 256}, false, ['encrypt']);
})
.then((aesKey: CryptoKey) => {
});
.then((passwordKey: CryptoKey) => {
const salt = window.crypto.getRandomValues(new Uint8Array(32));
return window.crypto.subtle.deriveKey({
name: 'PBKDF2',
salt,
iterations: 250000,
hash: {name: 'SHA-256'}
}, passwordKey, {name: 'AES-GCM', length: 256}, false, ['encrypt']);
})
.then((aesKey: CryptoKey) => {
});
Data to Encrypt
byte array form
.then((passwordKey: CryptoKey) => {
const salt = window.crypto.getRandomValues(new U
return window.crypto.subtle.deriveKey({
name: 'PBKDF2',
salt,
iterations: 250000,
hash: {name: 'SHA-256'}
}, passwordKey, {name: 'AES-GCM', length: 256},
})
.then((aesKey: CryptoKey) => {
});
AES-GCM
Crypto Key
Encrypt
@erniewturner
byte array form
Encrypted DataEncrypt
AES-GCM
Crypto Key
Initialization
Vector
Data to
Encrypt
Encrypt
window.crypto.subtle.encrypt(
algorithm: object,
key: CryptoKey,
data: Uint8Array
)
@erniewturner
.then((aesKey: CryptoKey) => {
const iv = window.crypto.getRandomValues(new Uint8Array(12));
return window.crypto.subtle.encrypt({
name: 'AES-GCM',
iv,
}, aesKey, dataAsBytes);
})
.then((encryptedContent: ArrayBuffer) => {
const encryptedBytes = new Uint8Array(encryptedContent);
});
.then((aesKey: CryptoKey) => {
const iv = window.crypto.getRandomValues(new Uint8Array(12));
return window.crypto.subtle.encrypt({
name: 'AES-GCM',
iv,
}, aesKey, dataAsBytes);
})
.then((encryptedContent: ArrayBuffer) => {
const encryptedBytes = new Uint8Array(encryptedContent);
});
.then((aesKey: CryptoKey) => {
const iv = window.crypto.getRandomValues(new Uint8Array(12));
return window.crypto.subtle.encrypt({
name: 'AES-GCM',
iv,
}, aesKey, dataAsBytes);
})
.then((encryptedContent: ArrayBuffer) => {
const encryptedBytes = new Uint8Array(encryptedContent);
});
.then((aesKey: CryptoKey) => {
const iv = window.crypto.getRandomValues(new Uint8Array(12));
return window.crypto.subtle.encrypt({
name: 'AES-GCM',
iv,
}, aesKey, dataAsBytes);
})
.then((encryptedContent: ArrayBuffer) => {
const encryptedBytes = new Uint8Array(encryptedContent);
});
Encrypted Data
.then((aesKey: CryptoKey) => {
const iv = window.crypto.getRandomValues(new Uint8Ar
return window.crypto.subtle.encrypt({
name: 'AES-GCM',
iv,
}, aesKey, dataAsBytes);
})
.then((encryptedContent: ArrayBuffer) => {
const encryptedBytes = new Uint8Array(encryptedConte
});
byte array form
Storage
256 bit = 32 byte (Uint8Array)
96 bit = 12 byte
(Uint8Array) > 0 bytes (Uint8Array)
@erniewturner
Salt Encrypted
Data
Initialization
Vector
PBKDF2 AES-GCM
Storage
32B Salt 12B IV Encrypted Data+ +
@erniewturner
Encrypted Data32B Salt 12B IV
Storage
@erniewturner
Storage
@erniewturner
Base64 String
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB…..…
.then((encryptedContent: ArrayBuffer) => {
const encryptedBytes = new Uint8Array(encryptedContent);
const encryptedPackage = concat(
salt,
iv,
encryptedBytes
);
return Base64.fromByteArray(encryptedPackage);
});
.then((encryptedContent: ArrayBuffer) => {
const encryptedBytes = new Uint8Array(encryptedContent);
const encryptedPackage = concat(
salt,
iv,
encryptedBytes
);
return Base64.fromByteArray(encryptedPackage);
});
.then((encryptedContent: ArrayBuffer) => {
const encryptedBytes = new Uint8Array(encryptedContent);
const encryptedPackage = concat(
salt,
iv,
encryptedBytes
);
return Base64.fromByteArray(encryptedPackage);
});
Decryption
@erniewturner
Get Encrypted Data
User Enters Password
Convert Password to CryptoKey
Derive AES Key
Decrypt Data
Decrypt
@erniewturner
DECRYPT
Decryption
@erniewturner
……..
Password
Decryption
EncryptedData32BSalt12BIV
@erniewturner
Decrypted
Data
Decrypt
PBKDF2
SHA-256
Crypto Key
Salt
AES-GCM
Crypto Key
Initialization
Vector
Encrypted
Data
function decryptData(encryptedData: string, password: string){
const encryptedBytes = Base64.toByteArray(encryptedData);
const salt = encryptedBytes.slice(0, 32);
const IV = encryptedBytes.slice(32, 12);
const encryptedData = encryptedBytes.slice(32 + 12);
}
function decryptData(encryptedData: string, password: string){
const encryptedBytes = Base64.toByteArray(encryptedData);
const salt = encryptedBytes.slice(0, 32);
const IV = encryptedBytes.slice(32, 12);
const encryptedData = encryptedBytes.slice(32 + 12);
}
function decryptData(encryptedData: string, password: string){
const encryptedBytes = Base64.toByteArray(encryptedData);
const salt = encryptedBytes.slice(0, 32);
const IV = encryptedBytes.slice(32, 12);
const encryptedData = encryptedBytes.slice(32 + 12);
}
Decrypt
window.crypto.decrypt(
algorithm: object,
key: CryptoKey,
data: Uint8Array
);
@erniewturner
return window.crypto.subtle.importKey(...)
.then(() => window.crypto.subtle.deriveKey(...))
.then((aesKey: CryptoKey) => {
return window.crypto.subtle.decrypt({
name: 'AES-GCM',
iv,
}, aesKey, encryptedData);
})
.then((decryptedContent: ArrayBuffer) => {
const decryptedBytes = new Uint8Array(decryptedContent);
});
}
return window.crypto.subtle.importKey(...)
.then(() => window.crypto.subtle.deriveKey(...))
.then((aesKey: CryptoKey) => {
return window.crypto.subtle.decrypt({
name: 'AES-GCM',
iv,
}, aesKey, encryptedData);
})
.then((decryptedContent: ArrayBuffer) => {
const decryptedBytes = new Uint8Array(decryptedContent);
});
}
return window.crypto.subtle.importKey(...)
.then(() => window.crypto.subtle.deriveKey(...))
.then((aesKey: CryptoKey) => {
return window.crypto.subtle.decrypt({
name: 'AES-GCM',
iv,
}, aesKey, encryptedData);
})
.then((decryptedContent: ArrayBuffer) => {
const decryptedBytes = new Uint8Array(decryptedContent);
});
}
return window.crypto.subtle.importKey(...)
.then(() => window.crypto.subtle.deriveKey(...))
.then((aesKey: CryptoKey) => {
return window.crypto.subtle.decrypt({
name: ‘AES-GCM',
iv,
}, aesKey, encryptedData);
})
.then((decryptedContent: ArrayBuffer) => {
const decryptedBytes = new Uint8Array(decryptedContent);
});
}
Important Notes
Key derivation will not fail if user enters wrong password
PBKDF2 Iterations must be the same on encrypt as on decrypt
There is no “forgot password” support
@erniewturner
There is no way to feature detect which algorithms are supported
POLYFILL
You CANNOT polyfill random number generation.
Stanford Javascript Crypto Library
@erniewturner
Title
PBKDF2 

(250K)
Native SJCL
1203ms
132ms
Native SJCL
Performance
@erniewturner
Desktop - MBP 2016
Title
PBKDF2 

(250K)
Native SJCL
4310ms
137ms
Native SJCL
Performance
@erniewturner
MOBILE - Pixel 1
Title
AES 

(1 KB)
Native SJCL
3.2ms
0.3ms
Native SJCL
Performance
@erniewturner
Desktop - MBP 2016
Title
AES 

(1 KB)
Native SJCL
4.8ms
1.1ms
Native SJCL
Performance
@erniewturner
MOBILE - Pixel 1
Title
AES 

(10MB)
Native SJCL
3015ms
27ms
Native SJCL
Performance
@erniewturner
Desktop - MBP 2016
Title
AES 

(10MB)
Native SJCL
7781ms
195ms
Native SJCL
Performance
@erniewturner
MOBILE - Pixel 1
WEB WORKERS
Bytes to encrypt/decrypt

User password bytes
Encrypted/decrypted bytes
MAIN
THREAD
WEB
WORKER
Thank You
@erniewturner
ernieturner
@ironcorelabs
ironcorelabs.com
Ernie Turner

Contenu connexe

Tendances

9 password security
9   password security9   password security
9 password security
drewz lin
 
amani_rwc_password
amani_rwc_passwordamani_rwc_password
amani_rwc_password
Arvind Mani
 

Tendances (20)

Python Cryptography & Security
Python Cryptography & SecurityPython Cryptography & Security
Python Cryptography & Security
 
9 password security
9   password security9   password security
9 password security
 
amani_rwc_password
amani_rwc_passwordamani_rwc_password
amani_rwc_password
 
Cargo Cult Security at OpenWest
Cargo Cult Security at OpenWestCargo Cult Security at OpenWest
Cargo Cult Security at OpenWest
 
iCloud keychain
iCloud keychainiCloud keychain
iCloud keychain
 
Encryption Boot Camp at Øredev
Encryption Boot Camp at ØredevEncryption Boot Camp at Øredev
Encryption Boot Camp at Øredev
 
Da APK al Golden Ticket
Da APK al Golden TicketDa APK al Golden Ticket
Da APK al Golden Ticket
 
How does cryptography work? by Jeroen Ooms
How does cryptography work?  by Jeroen OomsHow does cryptography work?  by Jeroen Ooms
How does cryptography work? by Jeroen Ooms
 
Jose Selvi - Side-Channels Uncovered [rootedvlc2018]
Jose Selvi - Side-Channels Uncovered [rootedvlc2018]Jose Selvi - Side-Channels Uncovered [rootedvlc2018]
Jose Selvi - Side-Channels Uncovered [rootedvlc2018]
 
JWTs and JOSE in a flash
JWTs and JOSE in a flashJWTs and JOSE in a flash
JWTs and JOSE in a flash
 
SSL/TLS for Mortals (DevNexus)
SSL/TLS for Mortals (DevNexus)SSL/TLS for Mortals (DevNexus)
SSL/TLS for Mortals (DevNexus)
 
JavaFest. Nanne Baars. Web application security for developers
JavaFest. Nanne Baars. Web application security for developersJavaFest. Nanne Baars. Web application security for developers
JavaFest. Nanne Baars. Web application security for developers
 
2018 SDJUG Deconstructing and Evolving REST Security
2018 SDJUG Deconstructing and Evolving REST Security2018 SDJUG Deconstructing and Evolving REST Security
2018 SDJUG Deconstructing and Evolving REST Security
 
Vault - Secret and Key Management
Vault - Secret and Key ManagementVault - Secret and Key Management
Vault - Secret and Key Management
 
2016 pycontw web api authentication
2016 pycontw web api authentication 2016 pycontw web api authentication
2016 pycontw web api authentication
 
Improving password-based authentication
Improving password-based authenticationImproving password-based authentication
Improving password-based authentication
 
HTTP For the Good or the Bad
HTTP For the Good or the BadHTTP For the Good or the Bad
HTTP For the Good or the Bad
 
Secure Storage: COMPOSABLE AND ROBUST OUTSOURCED STORAGE
Secure Storage: COMPOSABLE AND ROBUST OUTSOURCED STORAGESecure Storage: COMPOSABLE AND ROBUST OUTSOURCED STORAGE
Secure Storage: COMPOSABLE AND ROBUST OUTSOURCED STORAGE
 
Side-Channels on the Web: Attacks and Defenses
Side-Channels on the Web: Attacks and DefensesSide-Channels on the Web: Attacks and Defenses
Side-Channels on the Web: Attacks and Defenses
 
Cryptography For The Average Developer
Cryptography For The Average DeveloperCryptography For The Average Developer
Cryptography For The Average Developer
 

Similaire à Dodging WebCrypto API Landmines

Java Symmetric
Java SymmetricJava Symmetric
Java Symmetric
phanleson
 
Tutorial s crypto api session keys
Tutorial   s crypto api session keysTutorial   s crypto api session keys
Tutorial s crypto api session keys
Dr. Edwin Hernandez
 

Similaire à Dodging WebCrypto API Landmines (20)

Hadoop Security Now and Future
Hadoop Security Now and FutureHadoop Security Now and Future
Hadoop Security Now and Future
 
Django cryptography
Django cryptographyDjango cryptography
Django cryptography
 
Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)
Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)
Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)
 
Password (in)security
Password (in)securityPassword (in)security
Password (in)security
 
Basics of ssl
Basics of sslBasics of ssl
Basics of ssl
 
Java Symmetric
Java SymmetricJava Symmetric
Java Symmetric
 
Web cryptography javascript
Web cryptography javascriptWeb cryptography javascript
Web cryptography javascript
 
Encryption Boot Camp at JavaZone 2010
Encryption Boot Camp at JavaZone 2010Encryption Boot Camp at JavaZone 2010
Encryption Boot Camp at JavaZone 2010
 
Onward15
Onward15Onward15
Onward15
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
 
Securing TodoMVC Using the Web Cryptography API
Securing TodoMVC Using the Web Cryptography APISecuring TodoMVC Using the Web Cryptography API
Securing TodoMVC Using the Web Cryptography API
 
Cryptography 101 for_java_developers, Fall 2019
Cryptography 101 for_java_developers, Fall 2019Cryptography 101 for_java_developers, Fall 2019
Cryptography 101 for_java_developers, Fall 2019
 
Defending Against Attacks With Rails
Defending Against Attacks With RailsDefending Against Attacks With Rails
Defending Against Attacks With Rails
 
"Crypto wallets security. For developers", Julia Potapenko
"Crypto wallets security. For developers", Julia Potapenko"Crypto wallets security. For developers", Julia Potapenko
"Crypto wallets security. For developers", Julia Potapenko
 
{{more}} Kibana4
{{more}} Kibana4{{more}} Kibana4
{{more}} Kibana4
 
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 201910 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
 
SSL/TLS for Mortals (J-Fall)
SSL/TLS for Mortals (J-Fall)SSL/TLS for Mortals (J-Fall)
SSL/TLS for Mortals (J-Fall)
 
Tutorial s crypto api session keys
Tutorial   s crypto api session keysTutorial   s crypto api session keys
Tutorial s crypto api session keys
 
Random musings on SSL/TLS configuration
Random musings on SSL/TLS configurationRandom musings on SSL/TLS configuration
Random musings on SSL/TLS configuration
 
SSL/TLS for Mortals (GOTO Berlin)
SSL/TLS for Mortals (GOTO Berlin)SSL/TLS for Mortals (GOTO Berlin)
SSL/TLS for Mortals (GOTO Berlin)
 

Dernier

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 

Dernier (20)

%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 

Dodging WebCrypto API Landmines