Is there a cryptography algorithm for signing values with two keys and requiring both to verify it? - cryptography

Is there an algorithm that lets me sign a value with two keys at the same time, and in turn requires both keys to verify the signature?
Ie.
Sign X with Key1 and Key2 at the same time
Verify X is signed by these two keys
Like a joint bank account - to do anything on this account, the bank will require signatures from the two persons that initially created the account together.
I wouldn't bring the value into question, but the goal would be the ability to verify X was signed by two specific parties.

Related

Is there a one to one correlation between pub/priv key pairs and account IDs on the Hedera Network?

One public key usually corresponds to one or a specific number of addresses in other cryptocurrencies based on some algorithm.
https://testnet.dragonglass.me/hedera/transactions/0025330611632361982325526043
https://testnet.dragonglass.me/hedera/transactions/0025330611632362160372571164
In hedera, as the above two transactions have shown, using the same public key to send out two accountCreate transactions gives back two different accountId.
Is there an API whose params are a public key and who returns all the account Ids corresponding to the public key?
The mirror nodes support querying based on public key. However, Hedera's accounts are not 1:1 with a public key, you can't assume a public key is linked to a single account, in fact, the same public key can be used across multiple accounts meaning the same private key can sign transactions for all these accounts.
Furthermore, an account can be associated to a list of public keys meaning every key has to sign, or a threshold list which is a list where say 5 of 10 have to sign. All these can be nested too !
Finally, subject to having the private key to sign the transaction, you can update an account's public key. What you can't do is derive the account id from the public key. The account id comes from a sequence of numbers, each new entity (an account is an entity as are topics, tokens, etc...) is given the next id in the sequence.

How to secure a key in a distributed-hash-table so that only people with the private-key can write it?

I am trying to put together a distributed hash table (DHT) with a name system where one will be able claim ownership of any key.
What I have in mind is the following interface
dht.secure_set(public_key, signature, key, value)
where
signature == sign(private_key, public_key, key, value)`
That is the key-value pair is signed by signature.
Then, others will be able to retrieve value given they know the public_key and key:
dht.secure_get(public_key, key)
The peer responsible for key in the DHT will only accept updates to the (public_key, key) pair only if the signature is indeed the signature of the (key, value) pair.
Is this signature scheme secure?
I see at least two issues with that:
A) having the storage peer responsible for verification is not sufficient. it may be a malicious node, so readers will have to verify too
B) If there are many (key, pubkey) tuples with the same key but different pubkeys, i.e. some key being really popular, this can put an undue burden on a small fraction of the nodes in terms of CPU cycles they have to spend (if there are frequent writes), storage and traffic they have to serve.
It may be better to derive a final lookup key from (key, pubkey) through a hash function so that those tuples get scattered throughout the keyspace. This is in fact what the bittorrent DHT specifies for its generic value signed storage

Can you use username as unique identifier/primary key

Just a quick question on the best practise for the below case.
Developing a website with accounts. Website is setup so that no two accounts can have the same username i.e. all usernames are unique.
When persisting accounts in a database, is it ok to use the username as a primary key (unique identifier) or is there some reasons I should be aware of that would require a separately generated unique id?
Don't use username as primary key, never.
Use surrogate keys (ie autogenerated numbers), because
they are faster and smaller (key is 4-8 bytes, username is up to you dont know bytes?)
it is only right now you suppose usernames will be unique, later you will find out that you need non-unique usernames (for example for deleted users for which you have to save transaction history), or requirments will change
users should be able to change their username, in case of error/typo/etc
UPDATE: in case of distributed systems, use GUIDs

Usefulness of SQL column encryption

I have followed http://msdn.microsoft.com/en-us/library/ms179331.aspx for encrypting a column in SQL Server.
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'T3stP#ssword'
CREATE CERTIFICATE TestCert WITH SUBJECT = 'SSN Encryption'
CREATE SYMMETRIC KEY HRKey
WITH ALGORITHM = DES
ENCRYPTION BY CERTIFICATE TestCert;
OPEN SYMMETRIC KEY HRKey
DECRYPTION BY CERTIFICATE TestCert;
UPDATE [dbo].[Person]
SET [EncryptedSSN] = EncryptByKey(Key_GUID('HRKey'), CAST(SSN AS varchar(10)));
SELECT TOP 10 * FROM Person
1 Tom Thomson 111111111 0x0026DA624DBCA04CBCBF621FD5F......
2 Steve Stephenson 222222222 0x0026DA624DBCA04CBCBF6.....
Shows I have encrypted data, which is what I wanted.
OPEN SYMMETRIC KEY HRKey
DECRYPTION BY CERTIFICATE TestCert;
SELECT PersonID, Firstname, Lastname [SSN],
CONVERT(VARCHAR, DecryptByKey([EncryptedSSN]))
AS 'Decrypted SSN'
FROM [dbo].[Person]
1 Tom Thomson 111111111 111111111
2 Steve Stephenson 222222222 222222222
Close SYMMETRIC KEY HRKey
Ignoring that I still have an unencrypted column, the question is what has this really improved, it is simple for me to open the key and use it to decrypt the data.
I presume I'm missing some piece of understanding.
The key is associated with a user account, meaning one needs credentials to access the key. If a hacker can hijack that identity, your concerns apply. However, simply copying or stealing the IO subsystem is insufficient to break the encryption, nor is accessing the IO subsystem with a different account.
Additionally, for complete security, backup media have to be protected as well. Backing up unencrypted data creates another attack vector. If you run a SaaS for larger clients, or if you must comply with standards such as HIPAA or PCI, you may be required to ensure backups area encrypted.

What makes a keychain item unique (in iOS)?

My question concerns keychains in iOS (iPhone, iPad, ...). I think (but am not sure) that the implementation of keychains under Mac OS X raises the same question with the same answer.
iOS provides five types (classes) of keychain items. You must chose one of those five values for the key kSecClass to determine the type:
kSecClassGenericPassword used to store a generic password
kSecClassInternetPassword used to store an internet password
kSecClassCertificate used to store a certificate
kSecClassKey used to store a kryptographic key
kSecClassIdentity used to store an identity (certificate + private key)
After long time of reading apples documentation, blogs and forum-entries, I found out that a keychain item of type kSecClassGenericPassword gets its uniqueness from the attributes kSecAttrAccessGroup, kSecAttrAccount and kSecAttrService.
If those three attributes in request 1 are the same as in request 2, then you receive the same generic password keychain item, regardless of any other attributes. If one (or two or all) of this attributes changes its value, then you get different items.
But kSecAttrService is only available for items of type kSecClassGenericPassword, so it can't be part of the "unique key" of an item of any other type, and there seems to be no documentation that points out clearly which attributes uniquely determine a keychain item.
The sample code in the class "KeychainItemWrapper" of "GenericKeychain" uses the attribute kSecAttrGeneric to make an item unique, but this is a bug. The two entries in this example only are stored as two distinct entries, because their kSecAttrAccessGroup is different (one has the access group set, the other lets it free). If you try to add a 2nd password without an access group, using Apple's KeychainItemWrapper, you will fail.
So, please, answer my questions:
Is it true, that the combination of kSecAttrAccessGroup, kSecAttrAccount and kSecAttrService is the "unique key" of a keychain item whose kSecClass is kSecClassGenericPassword?
Which attributes makes a keychain item unique if its kSecClass is not kSecClassGenericPassword?
The primary keys are as follows (derived from open source files from Apple, see Schema.m4, KeySchema.m4 and SecItem.cpp):
For a keychain item of class kSecClassGenericPassword, the primary key is the combination of
kSecAttrAccount and kSecAttrService.
For a keychain item of class kSecClassInternetPassword, the primary key is the combination of kSecAttrAccount, kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol, kSecAttrAuthenticationType, kSecAttrPort and kSecAttrPath.
For a keychain item of class kSecClassCertificate, the primary key is the combination of kSecAttrCertificateType, kSecAttrIssuer and kSecAttrSerialNumber.
For a keychain item of class kSecClassKey, the primary key is the combination of kSecAttrApplicationLabel, kSecAttrApplicationTag, kSecAttrKeyType,
kSecAttrKeySizeInBits, kSecAttrEffectiveKeySize, and the creator, start date and end date which are not exposed by SecItem yet.
For a keychain item of class kSecClassIdentity I haven't found info on the primary key fields in the open source files, but as an identity is the combination of a private key and a certificate, I assume the primary key is the combination of the primary key fields for kSecClassKey and kSecClassCertificate.
As each keychain item belongs to a keychain access group, it feels like the keychain access group (field kSecAttrAccessGroup) is an added field to all these primary keys.
I was hitting a bug the other day (on iOS 7.1) that is related to this question. I was using SecItemCopyMatching to read a kSecClassGenericPassword item and it kept returning errSecItemNotFound (-25300) even though kSecAttrAccessGroup, kSecAttrAccount and kSecAttrService were all matching the item in the keychain.
Eventually I figured out that kSecAttrAccessible didn't match. The value in the keychain held pdmn = dk (kSecAttrAccessibleAlways), but I was using kSecAttrAccessibleWhenUnlocked.
Of course this value is not needed in the first place for SecItemCopyMatching, but the OSStatus was not errSecParam nor errSecBadReq but just errSecItemNotFound (-25300) which made it a bit tricky to find.
For SecItemUpdate I have experienced the same issue but in this method even using the same kSecAttrAccessible in the query parameter didn't work. Only completely removing this attribute fixed it.
I hope this comment will save few precious debugging moments for some of you.
Answer given by #Tammo Freese seems to be correct (but not mentioning all primary keys). I was searching for some proof in the documentation. Finally found:
Apple Documentation mentioning primary keys for each class of secret (quote below):
The system considers an item to be a duplicate for a given keychain when that keychain already has an item of the same class with the same set of composite primary keys. Each class of keychain item has a different set of primary keys, although a few attributes are used in common across all classes. In particular, where applicable, kSecAttrSynchronizable and kSecAttrAccessGroup are part of the set of primary keys. The additional per-class primary keys are listed below:
For generic passwords, the primary keys include kSecAttrAccount and
kSecAttrService.
For internet passwords, the primary keys include kSecAttrAccount,
kSecAttrSecurityDomain, kSecAttrServer, kSecAttrProtocol,
kSecAttrAuthenticationType, kSecAttrPort, and kSecAttrPath.
For certificates, the primary keys include kSecAttrCertificateType,
kSecAttrIssuer, and kSecAttrSerialNumber.
For key items, the primary keys include kSecAttrKeyClass,
kSecAttrKeyType, kSecAttrApplicationLabel, kSecAttrApplicationTag,
kSecAttrKeySizeInBits, and kSecAttrEffectiveKeySize.
For identity items, which are a certificate and a private key bundled
together, the primary keys are the same as for a certificate. Because
a private key may be certified more than once, the uniqueness of the
certificate determines that of the identity.
Here is another piece of useful information about uniqueness of a keychain item, found in the "Ensure Searchability" section of this Apple docs page.
To be able to find the item later, you’re going to use your knowledge of its attributes. In this example, the server and the account are the item’s distinguishing characteristics. For constant attributes (here, the server), use the same value during lookup. In contrast, the account attribute is dynamic, because it holds a value provided by the user at runtime. As long as your app never adds similar items with varying attributes (such as passwords for different accounts on the same server), you can omit these dynamic attributes as search parameters and instead retrieve them along with the item. As a result, when you look up the password, you also get the corresponding username.
If your app does add items with varying dynamic attributes, you’ll need a way to choose among them during retrieval. One option is to record information about the items in another way. For example, if you keep records of users in a Core Data model, you store the username there after using keychain services to store the password field. Later, you use the user name pulled from your data model to condition the search for the password.
In other cases, it may make sense to further characterize the item by adding more attributes. For example, you might include the kSecAttrLabel attribute in the original add query, providing a string that marks the item for the particular purpose. Then you’ll be able to use this attribute to narrow your search later.
Item of class kSecClassInternetPassword was used in the example, but there is a note that says:
Keychain services also offers the related kSecClassGenericPassword item class. Generic passwords are similar in most respects to Internet passwords, but they lack certain attributes specific to remote access (for example, they don’t have a kSecAttrServer attribute). When you don’t need these extra attributes, use a generic password instead.