I am using PhoneGap-NFC with Ionic/Capacitor and am trying to lock a NXP NTAG213.
According to the datasheet (https://www.nxp.com/docs/en/data-sheet/NTAG213_215_216.pdf) I have to write to page 0x2B to set the PWD, page 0x2C for the PACK.
const set_password_cmd = Uint8Array.from([
0xA2, //WRITE
0x2B, //address 2B
1, 2, 3, 4//pwd
]);
let res = await nfc.transceive(set_password_cmd);
const set_pack_cmd = Uint8Array.from([
0xA2, //WRITE
0x2C, //address 2C
2, 7, 0, 0//pack
]);
res = await nfc.transceive(set_pack_cmd);
Password should be 1234, pack should be 27.
Problem is I keep getting 0xA (LF) as a response to both commands and the tag does not lock itself.
PS. I am calling .connect(tech) and .close() afterwards inside a addTagDiscoveredListener call, sending a GET_VERSION command works as expected and returns correct data.
Remember that just setting a Password and Pack does not enable password protection by default, you also need to tell it what parts of the card to protect.
The default value of the AUTH0 byte (the fourth byte of page 0x29h on ntag213) is set to 0xFFh which means no pages are protected by the set password (See table 11 in Section 8.5.7 in the datasheet)
AUTH0 defines the page address from which the password verification is required. Valid address range for byte AUTH0 is from 00h to FFh. If AUTH0 is set to a page address which is higher than the last page from the user configuration, the password protection is effectively disabled
So you probably want to set the AUTH0 byte to a value of at least 0x4h (start of the user data area) or lower to enable password protection.
You should also check that that PROP access bits on page 0x2Ah for ntag 213 are set to your needs as the default is only to password protect write access
Related
First of all im Using TYPO3 Version 8.7.
The current problem i'm facing regards authentication of FrontendUser (fe_user) stored on a given page (in this case pid 168).
Apparently i'm trying to authenticate user with given credentials sent by a mobile application. I'm able to parse the user data and perform an authentication:
// plain-text password
$password = 'XXX';
// salted user password hash
$saltedPassword = 'YYY';
// keeps status if plain-text password matches given salted user password hash
$success = FALSE;
if (\TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::isUsageEnabled('FE')) {
$objSalt = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($saltedPassword);
if (is_object($objSalt)) {
$success = $objSalt->checkPassword($password, $saltedPassword);
}
}
While debugging this code snippet, i recognized the password sent by the user via Request, which gets encrypted with the given Salt algorithm change every time i retry this request. I'm not sure how to get a correct authentication, if the password changes constantly.
The $objSalt object contains the right Hashing Method($pbkdf2-sha256$25000), the password stored in the Database starts with the same prefix, but the actual payload is different.
So What is the exact problem or whats the thing i'm missing in the above code to complete the authentication?
Thanks for your help
BR,
Martin
the password sent by the user via Request, which gets encrypted with the given Salt algorithm change every time i retry this request
Yes, that because the salt is changed every time.
You should retrieve the salting instance with:
$instance = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($user['password']);
My application is linked with firebase database and authentication.
When a user creates an account, the only requirements for the password are for it to be 6 characters. Is there anyway I can make the password more complex, such as make them have a capital letter and a number.
Can I do this from firebase directly, or do I need to do this from my code?
There is no way to configure Firebase Authentication's rules for password strength.
Also see
Password Requirements when making an account with firrebase
Firebase Password Validation allowed regex.
You can (and should ) restrict it from your code. But you can't prevent malicious users from bypassing this by calling the API directly.
If the password strength is a hard requirement for your app, consider implementing custom authentication. This example of custom username (instead of email) and password authentication might be helpful.
Use this function. It includes range 6-15 i.e. minimum 6 and maximum 15 characters.One Capital letter , One number respectively.
func isValidPasswordString(pwdStr:String) -> Bool {
let pwdRegEx = "(?:(?:(?=.*?[0-9])(?=.*?[-!##$%&*ˆ+=_])|(?:(?=.*?[0-9])|(?=.*?[A-Z])|(?=.*?[-!##$%&*ˆ+=_])))|(?=.*?[a-z])(?=.*?[0-9])(?=.*?[-!##$%&*ˆ+=_]))[A-Za-z0-9-!##$%&*ˆ+=_]{6,15}"
let pwdTest = NSPredicate(format:"SELF MATCHES %#", pwdRegEx)
return pwdTest.evaluate(with: pwdStr)
}
This func will return true for valid password string
Based on the Google Developers site, it looks like apps can store emails and passwords into Smart Lock. Is there a way to also store phone numbers in Smart Lock? Very important for messaging apps.
Yes, you can store any string as the identifier when constructing a credential object, including phone numbers and general usernames, not just email addresses. Ensure to store any phone number in a format your app understands and can use when you retreive it from the API; identifiers will not be normalized in any way.
Example on Android (similar for web):
String phoneNumber = "+1 (650) 253-0000";
Credential credential = new Credential.Builder(phoneNumber)
.setPassword(password)
.build();
Auth.CredentialsApi.save(apiClient, credential).setResultCallback(new ResultCallback() {
public void onResult(Result result) {
Status status = result.getStatus();
if (status.isSuccess()) {
Log.d(TAG, "SAVE: OK");
// updates to existing credentials will succeed immediately
} else if (status.hasResolution()) {
// confirmation is required to save a new phone number
status.startResolutionForResult(this, RC_SAVE);
...
Note that if your phone number-based accounts don't have passwords, you could set the "account type" to your own URL instead of password for the credentials (i.e. .setAccountType(YOUR_URL) when building a credential).
See the developer docs for saving and retrieving credentials with Smart Lock for more information, and leave any follow-up questions in the comments.
I'm building a kext for an extra layer of security on OS X (built around KAtuh). I'm using a client in userspace that connects to the kext over sockets (as advised by Apple), and basically controls the kext. Because the product is supposed to provide extra security for OS X, it is important that it is "as secure as possible" against attacks. One attack vector is the following: A malicious process impersonates the client and sends malicious control data to the kext, disabling the security mechanism.. I want to prevent this by doing authentication upon connection. Here are my solutions:
Run the client as root, use CTL_FLAG_PRIVILEGED flag to ensure only root clients can connect to the kext. I'm not sure if I want to have my client run in privileged mode (again: extra attack vector).
Let the kext be connected to only one client. However, this is easily by-passable.
Ideally, I want to verify the identity of the client that connects through static int ctl_connect(kern_ctl_ref ctl_ref, struct sockaddr_ctl *sac, void **unitinfo). How can I do this?
I can also do packet authentication in static int ctl_set(kern_ctl_ref ctl_ref, u_int32_t unit, void *unitinfo, int opt, void *data, size_t len), however, I would have to come up with a dynamic shared secret. I was thinking about secret = SHA256(getUDID()), but AFAIK there are no crypto KPI's available, neither a way to getUDID() from kernelspace.
Are there any other idea's on doing "proper" authentication of clients?
I have asked Apple's Developer Tech Support this question, and they have said the only supported way to restrict user client access to kexts is to distinguish between root and non-root processes.
Personally, for the purposes of reducing the attack surface, it would indeed be useful to drop user client privileges. The Linux way of checking for a specific group membership seems like it should work on OS X too. (For example, you typically need to be part of the 'kvm' group to use the KVM virtualisation technology on Linux.) The only way to become a member of the group is via root privileges (setting up the Launch Daemon's GroupName requires root privileges) so this should be secure. I have yet to try this myself, but I've got 2 projects where this would make sense so I'll give it a go and will update this answer with my findings.
Apple has implemented functionality in the AMFI kext (<sys/codesign.h> header) that can be used to obtain the TeamID from a signed binary. If this header would be public, this is exactly what could be used to authenticate the client process connecting to the kext.
/*
* Function: csfg_get_teamid
*
* Description: This returns a pointer to
* the teamid for the fileglob fg
*/
const char *
csfg_get_teamid(struct fileglob *fg)
{
struct ubc_info *uip;
const char *str = NULL;
vnode_t vp;
if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE)
return NULL;
vp = (struct vnode *)fg->fg_data;
if (vp == NULL)
return NULL;
vnode_lock(vp);
if (!UBCINFOEXISTS(vp))
goto out;
uip = vp->v_ubcinfo;
if (uip == NULL)
goto out;
if (uip->cs_blobs == NULL)
goto out;
/* It is OK to extract the teamid from the first blob
because all blobs of a vnode must have the same teamid */
str = uip->cs_blobs->csb_teamid;
out:
vnode_unlock(vp);
return str;
}
How to add a parameters to the Google OAuth 2.0 redirect_uri?
Just like this:
redirect_uri=http://www.example.com/redirect.html?a=b
The b of a=b is random.
Anyone can help ?
You cannot add anything to the redirect uri, redirect uri is constant as set
in the app settings of Oauth.
eg :http://www.example.com/redirect.html
To pass several parameters to your redirect uri, have them stored in state
parameter before calling Oauth url, the url after authorization will send the same parameters to your redirect uri as
state=THE_STATE_PARAMETERS
So for your case,do this:
/1. create a json string of your parameters ->
{ "a" : "b" , "c" : 1 }
/2. do a base64UrlEncode , to make it URL safe ->
stateString = base64UrlEncode('{ "a" : "b" , "c" : 1 }');
This is a PHP example of base64UrlEncoding & decoding (http://en.wikipedia.org/wiki/Base64#URL_applications) :
function base64UrlEncode($inputStr)
{
return strtr(base64_encode($inputStr), '+/=', '-_,');
}
function base64UrlDecode($inputStr)
{
return base64_decode(strtr($inputStr, '-_,', '+/='));
}
So now state would be something like: stateString -> asawerwerwfgsg,
Pass this state in OAuth authorization URL:
https://accounts.google.com/o/oauth2/auth?
client_id=21302922996.apps.googleusercontent.com&
redirect_uri=https://www.example.com/back&
scope=https://www.google.com/m8/feeds/&
response_type=token&
state=asdafwswdwefwsdg,
For server side flow it will come along with token :
http://www.example.com/redirect.html?token=sdfwerwqerqwer&state=asdafwswdwefwsdg,
For client side flow it will come in the hash along with access token:
http://www.example.com/redirect.html#access_token=portyefghsdfgdfgsdgd&state=asdafwswdwefwsdg,
Retrieve the state, base64UrlDecode it, json_decode it, and you have your data.
See more about google OAuth 2 here:
http://code.google.com/apis/accounts/docs/OAuth2.html
Since the accepted answer does expose the actual data and misuses the state parameter instead of sticking to a nonce to protect against CSRF, I'll try to show a proper method. Rather than passing (read exposing) data it should be kept local. Hydrate it before the request and re-hydrate it after a validated request. "Validated" here means that the state-nonce of request and response match.
You need some kind of temporary client side storage. E.g. for SPA or general websites keep it in state or use the browser's localStorage, a session (or a signed cookie). For mobile apps they should use memory or any other local storage.
Before sending the request generate a nonce (see below) that will be used as state parameter for the request. Store the nonce together with the custom state (e.g. a json) in local storage.
For example, the nonce could be ih4f984hf and the custom state {"role": "customer"}. Then you could store data for re-hydration for that request like this:
"ih4f984hf": {
"role": "customer"
}
Then use only the nonce as value for the state parameter of the request. (If you absolutely want to combine the nonce and data into the state value be sure to encrypt it and be aware that the length of the value is limited!)
When receiving a response you get the value of the state parameter back. Look it up and if it matches the value in the local storage you may process the data using the stored state. If the nonces do not match the request is potentially from an attacker and should not be processed.
Generating the nonce
Remember that the nature of a nonce is that it is used once only and must be unpredictable! Unpredictable here means ideally random, but practically pseudo-random is ok if the entropry is high enough - in web apps you might want to check Web API Crypto which is supported pretty well.
For further readings this might be helpful:
http://www.thread-safe.com/2014/05/the-correct-use-of-state-parameter-in.html
https://datatracker.ietf.org/doc/html/draft-bradley-oauth-jwt-encoded-state-00
https://auth0.com/docs/protocols/state-parameters#set-and-compare-state-parameter-values
If you are in .NET you could save the parameters in the Session
HttpContext.Current.Session[{varname}]
and redirect to the authorization page without parameters
Response.Redirect(your_uri_approved_with_no_querystring_parameters);
In Javascript (Node), you could set the state property to an object of key value pairs.
const oAuth2Client = await new google.auth.OAuth2(
clientId: <clientId>,
clientSecret: <clientSecret>,
redirectUrl: <redirectUrl>,
);
return await oAuth2Client.generateAuthUrl({
access_type: "offline",
scope: <scopes>,
state: JSON.stringify({ a: "y", b: "z" }),
});
On google authorization complete, it returns of the state, code etc from ulr,
const params = JSON.parse(state); // { a: "y", b: "z" }
You can redirect parameter with url as below,
When you get response from google than you can pass parameter with url,
See below php code for same,
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL) . '?r=page/view');
}
In above example r=page/view is parameter on which i want the response with parameter