I have generated a private-public key pair using the web3j library.
ECKeyPair ecKeyPair = Keys.createEcKeyPair();
BigInteger publicKey = ecKeyPair.getPublicKey();
This returns an uncompressed form of the public key. I wanted to convert the same to a compressed format to generate the wallet using the below website.
https://lab.miguelmota.com/ethereum-public-key-to-address/example/
I know we can create the wallet directly using the Keypair, but I need this to work on the above website when I paste the public key.
I am using web3j version 5.0.0, and there is no built-in method to compress the public key.
Are there any other libraries or methods we can use to achieve the same
Try this for compressed public key - info from here
DeterministicSeed seed = new DeterministicSeed("some seed code here", null, "", 1409478661L);
DeterministicKeyChain chain = DeterministicKeyChain.builder().seed(seed).build();
DeterministicKey addrKey = chain.getKeyByPath(HDUtils.parsePath("M/44H/60H/0H/0/0"), true);
System.out.println("Address: " + Keys.getAddress(Sign.publicKeyFromPrivate(addrKey.getPrivKey()))); // mapper();
System.out.println("Uncompressed public key: " + Sign.publicKeyFromPrivate(addrKey.getPrivKey()).toString(16));
System.out.println("Compressed key: " + addrKey.getPublicKeyAsHex());
-- Output --
Address: 97f2582fec180600268ebae9a0052e676d876c27
Uncompressed public key: 37efe8e46dc39bee0f099871de99fe68a931730c02ef2918f832f30572b3f1a54f8d52fcaea129e31ac836063e2c432aac815cb86664165d1a226fe51a851d47
Compressed key: 0337efe8e46dc39bee0f099871de99fe68a931730c02ef2918f832f30572b3f1a5
Dependencies are as follows:
import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.crypto.HDUtils;
import org.bitcoinj.wallet.DeterministicKeyChain;
import org.bitcoinj.wallet.DeterministicSeed;
import org.bitcoinj.wallet.UnreadableWalletException;
import org.mapstruct.AfterMapping;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Keys;
import org.web3j.crypto.Sign;
<dependency>
<groupId>org.web3j</groupId>
<artifactId>crypto</artifactId>
<version>3.3.1-android</version>
</dependency>
<dependency>
<groupId>org.bitcoinj</groupId>
<artifactId>bitcoinj-core</artifactId>
<version>0.16.2</version>
</dependency>
Related
I want to extract CN from Kafka keystore.jks. This issue How to extract CN from X509Certificate in Java? can help you to extract CN from X509certificate, but it doesn't say how to extract from JKS and I spent a lot of time to get the right solution for my own question. I assume that my solution can help somebody to get the right answer faster. You should read keystore then convert to the X509 and take advantage of cryptacular lib (CertUtil.subjectCN). My code in Scala demonstrates this below.
That's my Scala code for extracting CN from JKS cert:
import org.cryptacular.util.CertUtil
import java.io.FileInputStream
import java.security.KeyStore
import java.security.cert.X509Certificate
....
val keystore = KeyStore.getInstance("JKS")
val keystoreLocation = new FileInputStream("your_path_to_the_certificate")
keystore.load(keystoreLocation, "your_password".toCharArray)
val aliases = keystore.aliases()
while (aliases.hasMoreElements) {
val alias = aliases.nextElement
logger.info("alias name: " + alias)
val certificate = keystore.getCertificate(alias).asInstanceOf[X509Certificate]
val CN = CertUtil.subjectCN(certificate)
logger.info("Common Name: " + CN)
}
I am using the IAIK wrapper to send pkcs11 requests to my Bull HSM. My objective is to generate a consistent key (token = true). The problem is that I always have this error code:
Exception in thread "main" iaik.pkcs.pkcs11.wrapper.PKCS11Exception: CKR_ATTRIBUTE_READ_ONLY
I can't understand why it's read-only? To initialize my Session I do so (using the RW_SESSION option):
import iaik.pkcs.pkcs11.Mechanism;
import iaik.pkcs.pkcs11.Module;
import iaik.pkcs.pkcs11.Session;
import iaik.pkcs.pkcs11.Token;
import iaik.pkcs.pkcs11.TokenException;
import iaik.pkcs.pkcs11.objects.AESSecretKey;
import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;
...
static String libP11 = "nethsm.dll";
static String hsmPassword = "123456";
static int hsmSlotId = 1;
private static void initHSM() throws IOException, TokenException{
Module module = Module.getInstance(libP11);
module.initialize(null);
Token token = module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT)[hsmSlotId - 1].getToken();
session = token.openSession(Token.SessionType.SERIAL_SESSION, Token.SessionReadWriteBehavior.RW_SESSION, null,
null);
session.login(Session.UserType.USER, hsmPassword.toCharArray());
}
My function to generate the key is the following:
private static AESSecretKey generateAESKey(byte[] keyValue, String label, int keyLength, boolean token) throws TokenException {
Mechanism keyGenerationMechanism = Mechanism.get(PKCS11Constants.CKM_AES_KEY_GEN);
AESSecretKey secretKeyTemplate = new AESSecretKey();
secretKeyTemplate.getValueLen().setLongValue(new Long(keyLength));
secretKeyTemplate.getLabel().setCharArrayValue(label.toCharArray());
secretKeyTemplate.getToken().setBooleanValue(token);
secretKeyTemplate.getSensitive().setBooleanValue(Boolean.FALSE);
secretKeyTemplate.getExtractable().setBooleanValue(Boolean.TRUE);
secretKeyTemplate.getDerive().setBooleanValue(Boolean.TRUE);
secretKeyTemplate.getModifiable().setBooleanValue(Boolean.TRUE);
secretKeyTemplate.getEncrypt().setBooleanValue(Boolean.TRUE);
secretKeyTemplate.getDecrypt().setBooleanValue(Boolean.TRUE);
secretKeyTemplate.getUnwrap().setBooleanValue(Boolean.TRUE);
secretKeyTemplate.getWrap().setBooleanValue(Boolean.TRUE);
secretKeyTemplate.getSign().setBooleanValue(Boolean.TRUE);
secretKeyTemplate.getVerify().setBooleanValue(Boolean.TRUE);
secretKeyTemplate.getValue().setByteArrayValue(keyValue);
return (AESSecretKey) session.generateKey(keyGenerationMechanism, secretKeyTemplate);
}
Any solutions please?
It does not make sense to use:
secretKeyTemplate.getValue().setByteArrayValue(keyValue)
to set key value (CKA_VALUE in PKCS#11) while generating new key -- HSM will generate key value for you. Remove this line.
Note: If you want to create key with a given value try C_CreateObject (Session.createObject in IAIK Wrapper) instead -- but not all HSMs support this way. If you fail to create key with a known value using this method you will have to use C_UnwrapKey to import encrypted key value which usually works.
Good luck with your project!
It is possible to generate a valid legacy bitcoin key pair with the following code which is using bitcoinj master branch:
import org.bitcoinj.core.Address;
import org.bitcoinj.core.DumpedPrivateKey;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.NetworkParameters;
public class GeneratePrivateKeyBulk {
public static void main(String[] args) {
ECKey key = new ECKey();
Address pubAddress = new Address(NetworkParameters.prodNet(), key.getPubKeyHash());
DumpedPrivateKey privKey = key.getPrivateKeyEncoded(NetworkParameters.prodNet());
System.out.println("Public address: " + pubAddress.toBase58() + "; Private key: " + privKey.toBase58());
}
}
This creates a usable legacy base58 encoded public address and private key e.g. like 1ERzRYYdbibaQt2kuNfgH8spuoqQxYkwQb, L3AuZ2vNt11ac2xSi6AYwzXyftqSVPcSuHNdTsSuRfknXvoRtWzF correspondingly.
The question is how can I do the same operation to obtain a segwit key pair?
I looked at the bitcoinj docs but could not find any API for generating addresses directly as segwit.
By looking at the tests and the segwit pull request I found that the following code (appended to the code above) would produce a segwit address (i.e. one that starts with 3, e.g. 31uLnxKteEYa2u1vgWyVPkTpVfUGduCV82)
Script script = ScriptBuilder.createP2SHOutputScript(1, Collections.singletonList(key));
Address segwitAddress = Address.fromP2SHScript(NetworkParameters.prodNet(), script);
System.out.println("Segwit address: " + segwitAddress.toBase58());
My understanding is that the code above is supposed to be used in a multisig scenario, therefore I am not sure if this is the correct way to derive a segwit address from a single private key. Is this the correct/reliable/safe code for generating a paper segwit wallet?
Also, is there a way to add BIP38 password protection to the private key using bitcoinj? The class BIP38PrivateKey only has methods for decrypting a BIP38 key from an existing base58 representation, but no methods for BIP38 password encryption.
Hi I'm trying to create a java program which checks for a value present in the amazon dynamodb.
Well actually im trying to write a java program for a retail store where the program checks for a certain product(value) in the dynamodb and returns the quantity present in the store.I already created a table in dynamodb and also used the scan api to retrieve items.But now i want to search for a certain value is present or not and also return the quantity present.
It would be really helpful if anyone could help me with a snippet.
ps: i'm new to java
Thanks
Given following data modelling for a table ConsumerTable, with leaseKey as indexed field;
{
"checkpoint": "49572533067729099438069946639296561054199125138133221378",
"checkpointSubSequenceNumber": 0,
"leaseCounter": 1372794,
"leaseKey": "shardId-000000000000",
"leaseOwner": "pout_172.21.63.243",
"ownerSwitchesSinceCheckpoint": 0
}
Java API to query Amazon DynamoDB by the indexed field would be
import com.amazonaws.ClientConfiguration;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.retry.v2.RetryPolicy;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
public AmazonDynamoDB getDbConnection() {
AmazonDynamoDBClient dynamoDB = new AmazonDynamoDBClient( new ProfileCredentialsProvider("your-aws-auth-profile_in_~/.aws/credentials"));
dynamoDB.setRegion(Region.getRegion(Regions.US_WEST_2))
return dynamoDB;
}
public void getData() {
DynamoDB dynamoDB = new DynamoDB(getDbConnection());
Table consumerOffsetTable = dynamoDB.getTable("ConsumerTable");
Optional.ofNullable(consumerOffsetTable.getItem("leaseKey", "shardId-000000000000")).ifPresent(item -> {
Map<String, Object> itemMap = item.asMap();
System.out.println(itemMap.get("leaseKey").toString() + " -> " + itemMap.get("checkpoint").toString());
});
}
Maven dependency would be
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
<version>1.11.115</version>
</dependency>
In your product, quantity example, index product attribute and query should be similar to above example.
Resources
For AWS access using SDK - http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html
For Dynamodb apis
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ScanJavaDocumentAPI.html
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryingJavaDocumentAPI.html
I am trying to read AWS parameters from the parameter store using java, i have created the parameters using a custom encryption key. I dont see a sample code in the internet where its using a custom KMS key , the below is the code i currently have which is working (here we are usingthe default KMS key).
AWSSimpleSystemsManagement client= AWSSimpleSystemsManagementClientBuilder.defaultClient();
GetParametersRequest request= new GetParametersRequest();
request.withNames("test.username","test.password")
.setWithDecryption(true);
This will give the results with default KMS key
Does anyone know how to handle this if we have a custom KMS key
just in case, if somebody looking for this (with Default encryption Key)
protected Parameter getParameterFromSSMByName(String parameterKey)
{
AWSCredentialsProvider credentials = InstanceProfileCredentialsProvider.getInstance();
AWSSimpleSystemsManagement simpleSystemsManagementClient = (AWSSimpleSystemsManagement)((AWSSimpleSystemsManagementClientBuilder)((AWSSimpleSystemsManagementClientBuilder)AWSSimpleSystemsManagementClientBuilder.standard().withCredentials(credentials)).withRegion("us-east-1")).build();
GetParameterRequest parameterRequest = new GetParameterRequest();
parameterRequest.withName(parameterKey).setWithDecryption(Boolean.valueOf(true));
GetParameterResult parameterResult = simpleSystemsManagementClient.getParameter(parameterRequest);
return parameterResult.getParameter();
}
Here is #Extreme's answer as a class with imports and a bit of cleanup:
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.InstanceProfileCredentialsProvider;
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement;
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder;
import com.amazonaws.services.simplesystemsmanagement.model.GetParameterRequest;
import com.amazonaws.services.simplesystemsmanagement.model.GetParameterResult;
public class AWSSsmHelper
{
private AWSCredentialsProvider credentials = InstanceProfileCredentialsProvider.getInstance();
private AWSSimpleSystemsManagement simpleSystemsManagementClient =
AWSSimpleSystemsManagementClientBuilder.standard().withCredentials(credentials)).withRegion("us-east-1")).build();
public String getParameterFromSSMByName(String parameterKey) {
GetParameterRequest parameterRequest = new GetParameterRequest();
parameterRequest.withName(parameterKey).setWithDecryption(Boolean.valueOf(true));
GetParameterResult parameterResult = simpleSystemsManagementClient.getParameter(parameterRequest);
return parameterResult.getParameter().getValue();
}
}
For GetParameters API, there's no difference between use default KMS key or custom KMS key. It always works like your code. Just make sure the permission for the credential includes the custom key.
The difference only at PutParameter API, when using a default KMS key, you don't need to specify it, when using a custom KMS key, you set its KeyId to the custom key. The KeyId can be one of following examples:
Key ARN Example arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012
Alias ARN Example - arn:aws:kms:us-east-1:123456789012:alias/MyAliasName
Globally Unique Key ID Example - 12345678-1234-1234-1234-123456789012
Alias Name Example - alias/MyAliasName